3

The SelectedItemChanged event and SelectedItem property of TreeView do not occur when the TreeViewItem is an input control like Textbox. The sample code below illustrates the problem by placing a breakpoint in TreeView SelectedItemChanged event. This breakpoint will fire when "String Header" is selected, but not "Textbox Header".

I assume that the Textbox or RichTextbox (My real application) is eating some vital bubbling event. How can I get the TreeView SelectedItem to behave for a TextBox as it would for control like Label?

Note: If I can solve this issue I will need to two-way bind to SelectedItem as I am using MVVM and MEF. SelectedItem is readonly which is problem, which I plan to solve with ( http://silverscratch.blogspot.com/2010/11/two-way-binding-on-treeviewselecteditem.html ). I thought this related link might help someone.

XAML:

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

Code Behind:

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

Thanks,

aidesigner
  • 553
  • 2
  • 8
  • 15

1 Answers1

1

You should catch GotFocus event on your 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;
}

The implementation of TryFindParent you may found here:
https://stackoverflow.com/a/4838168/1088908

Community
  • 1
  • 1
asktomsk
  • 2,289
  • 16
  • 23
  • I am afraid I over simplified my problem. The textbox TreeViewItems of my TreeView actual come from 3rd party assemblies by means of MEF. Long story short I must handle the events on TreeView. However, do you think I can/should handle this bubbling GotFocus event at the TreeView level? – aidesigner Mar 25 '12 at 03:26
  • Sure it will works even you'll move GotFocus="UIElement_OnGotFocus" to TreeView. But do not forget to add this check at handler: item != null (I've updated the answer) – asktomsk Mar 25 '12 at 04:11
  • Awesome it worked! If I may, I have to closing questions. 1) For understanding purposes do you know why SelectedItemChanged works automatically for TreeViewItems content like Label and not Textbox - what is the absent bubbling event? 2) In your linked GetParentObject method the last resort is to use VisualTreeHelper. Why is it not sufficient to just use VisualTreeHelper to find parent? – aidesigner Mar 25 '12 at 12:43
  • 1. I don't know exactly but feel that problem in keyboard focus. You know that WPF operate with two focuses: "keyboard" and "logical" and there is no direct dependance between them. In case with TextBox it catch "keyboard" focus but not "logical"... 2. I found this method a long time ago and many WPF-driven peoples uses it often in examples. I use it in many places in my projects and it works perfectly :) Here is the version with good comments https://sites.google.com/site/bobstechwiki/home/wpf-ji-shu-1/find-element-by-visual-tree – asktomsk Mar 25 '12 at 13:47
  • I tried this method and it selects the TreeViewItem when I click the TextBox, but it does not put the cursor in the TextBox until I click the TextBox again (while the TreeViewItem is selected). Is there a way to select the TreeViewItem and still keep the edit mode active on the first click? – R1PFake Apr 09 '21 at 20:09