Click here to Skip to main content
15,907,001 members
Please Sign up or sign in to vote.
3.00/5 (2 votes)
See more:
Hi!

I would like to create a treeview, that behaves the following way: If I click on an item in the treeview, the item will be selected. This is the default behaviour, if I use a treeview with TextBlocks. But if I use TextBoxes instead, the behaviour is lost. The item will only be selected, if I click on the border of the item. I use the following code to repair this:

XML
<TreeView.Resources>
    <Style TargetType="TreeViewItem">
        <Style.Triggers>
            <Trigger Property="FrameworkElement.IsKeyboardFocusWithin" Value="True">
                <Setter Property="IsSelected" Value="True" />
            </Trigger>
        </Style.Triggers>
    </Style>
</TreeView.Resources>


It works quite fine, but if I select a child item before the parent, the parent will be selected, and if I select a parent before its child items and I select the parent again, the parent won't be selected. I don't really understand why. Could someone give a solution to this problem?
Posted
Comments
Sergey Alexandrovich Kryukov 27-Jun-12 13:56pm    
Yes, this is a problem; I voted 5 for the question.
--SA

Thanks for a nice question. I think there could be several solutions for that. One solution could be to find the Visual Parent in the Code behind and then select the treeViewitem. So What i have done is given below,

The XAML Code,

C#
<StackPanel>
       <TreeView>
           <TreeView.Resources>
               <Style TargetType="TreeViewItem">
                   <Setter Property="Padding" Value="5"/>
                   <Setter Property="HeaderTemplate">
                       <Setter.Value>
                           <DataTemplate>
                               <TextBox Text="{Binding Mode=OneWay}"  IsKeyboardFocusedChanged="TextBox_IsKeyboardFocusedChanged"/>
                           </DataTemplate>
                       </Setter.Value>
                   </Setter>
                   <!--<Style.Triggers>
                       <Trigger Property="IsKeyboardFocusWithin" Value="True">
                           <Setter Property="IsSelected" Value="True"/>
                       </Trigger>
                   </Style.Triggers>-->
               </Style>
           </TreeView.Resources>
           <TreeViewItem Header="One">
               <TreeViewItem Header="ChildOne"/>
           </TreeViewItem>
           <TreeViewItem Header="One">
               <TreeViewItem Header="ChildOne"/>
           </TreeViewItem>
           <TreeViewItem Header="One">
               <TreeViewItem Header="ChildOne"/>
           </TreeViewItem>
       </TreeView>
       <TreeView>
           <TreeViewItem Header="One">
               <TreeViewItem Header="ChildOne"/>
           </TreeViewItem>
           <TreeViewItem Header="One">
               <TreeViewItem Header="ChildOne"/>
           </TreeViewItem>
           <TreeViewItem Header="One">
               <TreeViewItem Header="ChildOne"/>
           </TreeViewItem>
       </TreeView>
   </StackPanel>


And in the code behind you need to write some code,

C#
private void TextBox_IsKeyboardFocusedChanged(object sender, DependencyPropertyChangedEventArgs e)
       {
           if (Convert.ToBoolean(e.NewValue) == true)
           {
               var v = FindVisualParent<TreeViewItem>(sender as UIElement);
               v.IsSelected = true;
           }

       }

       public static T FindVisualParent<T>(UIElement element) where T : UIElement
       {
           UIElement parent = element; while (parent != null)
           {
               T correctlyTyped = parent as T; if (correctlyTyped != null)
               {
                   return correctlyTyped;
               }
               parent = VisualTreeHelper.GetParent(parent) as UIElement;
           } return null;
       }



That's all. Enjoy it.
 
Share this answer
 
I would be interested is seeing a full example. I might suggest trying code behind instead. Since this is a View issue that should be fine, keeping with the MVVM pattern. Voted 5 for question.
 
Share this answer
 
Comments
Clifford Nelson 29-Jun-12 12:08pm    
Whoever gave me the one, my code behind was obviously the solution. If I had had more code, I would have gotten further, like the solution.
Thank you for the hint and the code. I added finally a handler to the GotKeyboardFocus event of the TextBox the following way, and it works fine.

private void TextBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
    DependencyObject item = sender as DependencyObject;

    while (item != null && !(item is TreeViewItem))
    {
        item = VisualTreeHelper.GetParent(item);
    }

    if (item != null)
    {
        ((TreeViewItem)item).IsSelected = true;
    }
}
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900