Поведение TreeView SelectedItem с дочерними элементами TextBox

Событие SelectedItemChanged и свойство SelectedItem TreeView не возникают, если TreeViewItem является элементом управления вводом, таким как Textbox. Приведенный ниже пример кода иллюстрирует проблему, помещая точку останова в событие TreeView SelectedItemChanged. Эта точка останова срабатывает, когда выбран «Заголовок строки», но не «Заголовок текстового поля».

Я предполагаю, что Textbox или RichTextbox (мое настоящее приложение) поглощает какое-то жизненно важное событие всплытия. Как я могу заставить TreeView SelectedItem вести себя для TextBox, как для элемента управления, такого как Label?

Примечание. Если я смогу решить эту проблему, мне потребуется двусторонняя привязка к SelectedItem, поскольку я использую MVVM и MEF. SelectedItem доступен только для чтения, и это проблема, которую я планирую решить с помощью (http://silverscratch.blogspot.com/2010/11/two-way-binding-on-treeviewselecteditem.html). Я думал, что эта ссылка может кому-то помочь.

XAML:

<TreeView SelectedItemChanged="TreeView_SelectedItemChanged">
    <TreeViewItem>
        <TreeViewItem.Header>
            <TextBox>
                Textbox Header
            </TextBox>
        </TreeViewItem.Header>
    </TreeViewItem>
    <TreeViewItem>
        <TreeViewItem.Header>
            String Header
        </TreeViewItem.Header>
    </TreeViewItem>
</TreeView>

Код позади:

    private void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    {
        // Breakpoint will fire when "String Header" Selected
        // !!! Breakpoint does not fire when Textbox Selected
        var newValue = e.NewValue;
        var oldValue = e.OldValue;
    }

Спасибо,


person aidesigner    schedule 25.03.2012    source источник


Ответы (1)


Вы должны поймать GotFocus событие на своем TreeView:

<TreeView SelectedItemChanged="TreeView_SelectedItemChanged"
          GotFocus="UIElement_OnGotFocus">
   <TreeViewItem>
      <TreeViewItem.Header>
          <TextBox>Textbox Header</TextBox>
       </TreeViewItem.Header>
   </TreeViewItem>
   <TreeViewItem>
        <TreeViewItem.Header>String Header</TreeViewItem.Header>
   </TreeViewItem>
 </TreeView>

private void UIElement_OnGotFocus(object sender, RoutedEventArgs e)
{
    TreeViewItem item = UIHelpers.TryFindParent<TreeViewItem>   
                           ((DependencyObject) e.OriginalSource);
    if (item != null)
          item.IsSelected = true;
}

Реализацию TryFindParent вы можете найти здесь:
https://stackoverflow.com/a/4838168/1088908

person asktomsk    schedule 25.03.2012
comment
Боюсь, я слишком упростил свою задачу. Текстовое поле TreeViewItems моего TreeView фактически поступает из сторонних сборок с помощью MEF. Короче говоря, я должен обрабатывать события в TreeView. Однако как вы думаете, я могу / должен обрабатывать это всплывающее событие GotFocus на уровне TreeView? - person aidesigner; 25.03.2012
comment
Конечно, это сработает, даже если вы переместите GotFocus = UIElement_OnGotFocus в TreeView. Но не забудьте добавить эту проверку в обработчике: item! = Null (я обновил ответ) - person asktomsk; 25.03.2012
comment
Потрясающе это сработало! Если можно, у меня есть заключительные вопросы. 1) Для понимания знаете ли вы, почему SelectedItemChanged автоматически работает для содержимого TreeViewItems, такого как Label, а не Textbox - что такое отсутствующее событие всплытия? 2) В вашем связанном методе GetParentObject последнее средство - использовать VisualTreeHelper. Почему для поиска родителя недостаточно просто использовать VisualTreeHelper? - person aidesigner; 25.03.2012
comment
1. Точно не знаю, но чувствую эту проблему с фокусом на клавиатуре. Вы знаете, что WPF работает с двумя направлениями: клавиатурным и логическим, и между ними нет прямой зависимости. В случае с TextBox он улавливает фокус клавиатуры, но это не логично ... 2. Я нашел этот метод давно, и многие люди, использующие WPF, часто используют его в примерах. Я использую его во многих местах в своих проектах, и он отлично работает :) Вот версия с хорошими комментариями sites.google.com/site/bobstechwiki/home/wpf-ji-shu-1/ - person asktomsk; 25.03.2012
comment
Я пробовал этот метод, и он выбирает TreeViewItem, когда я нажимаю TextBox, но он не помещает курсор в TextBox, пока я снова не щелкну TextBox (пока выбран TreeViewItem). Есть ли способ выбрать TreeViewItem и по-прежнему активировать режим редактирования при первом щелчке? - person R1PFake; 09.04.2021