2009-11-23 2 views
4

Я создаю пользовательский UserControl, который будет использоваться внутри шаблона редактирования DataGrid. Это выглядит следующим образом:WPF Всплывающее фокус в сетке данных

<UserControl 
    x:Class="HR.Controls.UserPicker" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:tk="http://schemas.microsoft.com/wpf/2008/toolkit" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 

    <Grid> 
     <TextBlock x:Name="PART_TextBox" Text="Hello WOrld" /> 
     <Popup Width="234" Height="175" IsOpen="True" StaysOpen="True" 

      Placement="Bottom" 
      PlacementTarget="{Binding ElementName=PART_TextBox}" 
     > 
      <TextBox 
        x:Name="searchTextBox" 
        Text="&gt;Enter Name&lt;"/> 
     </Popup> 
    </Grid> 
</UserControl> 

редактировать: Я сузил код немного. Кажется, что если я помещаю всплывающее окно с текстовым полем внутри CellEditingTemplate, текстовое поле не будет фокусироваться без проблем. Когда я переношу этот код в UserControl, я больше не могу выбирать текстовое поле при редактировании ячейки.

Является ли UserControl чем-то смешным с фокусом?


Проблема заключается в том, когда я изменить ячейку в сетке я получаю пользовательский элемент управления, показывая вверх, но я не могу нажать на TextBox searchTextBox. Когда я нажимаю на него, всплывающее окно закрывается, и ячейка возвращается к умолчанию.

Я пробовал копировать и вставлять весь код внутри пользовательского элемента управления и вставлять его непосредственно в CellEditingTemplate и взаимодействует так, как должен.

Мне просто интересно, сделал ли UserControl что-то странное, что не позволяет фокусу всплывать, потому что он работает так, как ожидалось, когда он непосредственно помещается в CellEditingTemplate?

Спасибо, Рауль

+1

Ну UserControl есть что-то странное с ним, что не лечить фокус всплывающего окна, чтобы быть частью его собственной личности. Поэтому мне пришлось создать пользовательский контроль и поцарапать UserControl. Это была боль, но стоящая за свободу, которую вы получаете. – HaxElit

ответ

2

У меня был своего рода Двойники проблемы, я создал UserControl, содержащую текстовое поле, кнопка и календарь. Basicaly Я создаю свой собственный datepicker с пользовательской логикой проверки.

Я поместил этот компонент в CellEditingTemplate. Когда я нажал кнопку, всплывающее окно показало, но щелчок по всплывающему окну в любом месте вызывал редактирование ячейки (поскольку всплывающее окно фокусировалось на текстовом поле). Я решил это, добавив код, который говорит, что если всплывающее окно открыто, фокус текстового поля не может быть потерян. Это помогло мне.

Кроме того, в обработчике обработчика on usercontrol я уделяю внимание текстовому поле. В вашем случае это возможно с помощью Usercontrol itsefl с фокусом.

protected override void OnPreviewLostKeyboardFocus(KeyboardFocusChangedEventArgs e) { 
      // Don't allow focus to leave the textbox if the popup is open 
      if (Popup.IsOpen) e.Handled = true; 
} 

private void Root_Loaded(object sender, RoutedEventArgs e) { 
     TextBox.Focus(); 
} 
3

У меня была аналогичная проблема, где Popup внедренный в UserControl как шаблон редактирования ячейки будет закрыть, когда были нажаты некоторые районы этого. Проблема оказалась в том, что WPF Toolkit (и предположительно WPF4) DataGrid очень жадна левыми щелчками мыши. Даже когда вы обрабатываете их и устанавливаете Handled на true, сетка может интерпретировать их как щелчок в другую ячейку.

Это thread имеет полную информацию, но исправление вклиниться в DataGrid.CellEditEnding событие и отменить конец редактирования:

private static void DataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e) 
{ 
    if (e.Column.GetType() == typeof(DataGridTemplateColumn)) 
    { 
     var popup = GetVisualChild<Popup>(e.EditingElement); 
     if (popup != null && popup.IsOpen) 
     { 
      e.Cancel = true; 
     } 
    } 
} 

private static T GetVisualChild<T>(DependencyObject visual) 
    where T : DependencyObject 
{ 
    if (visual == null) 
     return null; 

    var count = VisualTreeHelper.GetChildrenCount(visual); 
    for (int i = 0; i < count; i++) 
    { 
     var child = VisualTreeHelper.GetChild(visual, i); 

     var childOfTypeT = child as T ?? GetVisualChild<T>(child); 
     if (childOfTypeT != null) 
      return childOfTypeT; 
    } 

    return null; 
} 

Полный кредит на это идет к Actipro thread.

+0

Работает как шарм !! – JanW

3

Не уверен, что это поможет кому угодно, но это поможет, если у вас есть настраиваемые элементы управления в datagrid с всплывающим окном ..... это фиксировало мою проблему, и это была одна строка xaml. Я целый день перечитываю этот форум, а затем смотрю на источник для DataGridCell. Надеюсь это поможет.

<Style TargetType="{x:Type DataGridCell}"> 
     <Setter Property="Focusable" Value="False"></Setter> 
    </Style> 
+1

Это простейшее рабочее решение, позволяющее получить всплывающее окно внутри DataGridCell. – Abbas

Смежные вопросы