WPF Popup focus в сетке данных

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

<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>

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

UserControl делает что-то забавное с фокусом?


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

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

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

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


person HaxElit    schedule 23.11.2009    source источник
comment
Что ж, в UserControl есть что-то странное, что не рассматривает фокус Popup как часть самого себя. В итоге мне пришлось создать Custom Control и поцарапать UserControl. Это было больно, но оно того стоило за полученную свободу.   -  person HaxElit    schedule 04.12.2009


Ответы (4)


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

Эта ветка содержит полную информацию, но исправление состоит в том, чтобы подключиться к событию 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 .

person bruceboughton    schedule 08.03.2012

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

    <Style TargetType="{x:Type DataGridCell}">
        <Setter Property="Focusable" Value="False"></Setter>
    </Style>
person TravisWhidden    schedule 02.08.2013
comment
Это простейшее возможное рабочее решение для всплывающего окна внутри DataGridCell. - person Abbas; 12.01.2017

У меня была похожая проблема: я создал пользовательский элемент управления, содержащий текстовое поле, кнопку и календарь. В основном я создаю свой собственный datepicker с настраиваемой логикой проверки.

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

Кроме того, в загруженном обработчике событий пользовательского управления я уделяю внимание текстовому полю. В вашем случае, вероятно, это 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();
}
person nick    schedule 01.10.2010

Установите FocusManager. IsFocusScope присоединенное свойство во всплывающем окне к True

person google dev    schedule 14.05.2017