How to expand WPF TreeView on single click of item

Maybe is not the most elegant solution but this works:

    static DependencyObject VisualUpwardSearch<T>(DependencyObject source)
    {
        while (source != null && source.GetType() != typeof(T))
            source = VisualTreeHelper.GetParent(source);

        return source;
    }

then in the TreeViewItem.Selected Handler:

        private void Treeview_Selected(object sender, RoutedEventArgs e)
        {
            var treeViewItem = VisualUpwardSearch<TreeViewItem>(e.OriginalSource as DependencyObject) as TreeViewItem;
            if (treeViewItem != null) treeViewItem.IsExpanded = true;
        }

the VisualUpwardSearch magic is taken from here: Select TreeView Node on right click before displaying ContextMenu

Regards


I had the same problem and I did it with the Style functionnality so that you don't need to handle the event.

I defined a style for the TreeViewItem

<Style x:Key="{x:Type TreeViewItem}" TargetType="{x:Type TreeViewItem}">
    <!--<Setter Property="FocusVisualStyle" Value="{StaticResource TreeViewItemFocusVisual}"/>-->
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TreeViewItem}">
                        <CheckBox Style="{StaticResource TreeViewItemCB}" IsChecked="{Binding Path=IsExpanded,Mode=OneWayToSource,RelativeSource={RelativeSource TemplatedParent}}"  ClickMode="Press">
                            <Grid Background="{StaticResource TreeViewItemBackground}" Margin="0">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition/>
                            </Grid.RowDefinitions> 
                            <Border Name="Bd">
                                    <ContentPresenter x:Name="PART_Header" ContentSource="Header"/>
                            </Border>
                            <ItemsPresenter x:Name="ItemsHost" Grid.Row="1"/>
                            </Grid>
                        </CheckBox>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

The important part is to defined the checkBox in the ControlTemplate and the binding with it. When the CheckBox is checked, the item will be expanded with just one click.

<CheckBox Style="{StaticResource TreeViewItemCB}" IsChecked="{Binding Path=IsExpanded,Mode=OneWayToSource,RelativeSource={RelativeSource TemplatedParent}}"  ClickMode="Press">

this is the style for the checkBox so that it stretches and doesn't display the box with the stroke.

<Style x:Key="TreeViewItemCB" TargetType="CheckBox" BasedOn="{StaticResource baseStyle}">
    <Setter Property="SnapsToDevicePixels" Value="true"/>
    <Setter Property="OverridesDefaultStyle" Value="true"/>
    <Setter Property="KeyboardNavigation.TabNavigation" Value="None" />
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="VerticalAlignment" Value="Stretch"/>
    <Setter Property="HorizontalAlignment" Value="Stretch"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="CheckBox">
                <ContentPresenter VerticalAlignment="Stretch" HorizontalAlignment="Stretch" RecognizesAccessKey="True"/>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

I had this same problem and found a good solution thanks to another StackOverflow post.

In the control.xaml's TreeView element, you can hook directly into the TreeViewItem's Selected event:

<TreeView ItemsSource="{StaticResource Array}" TreeViewItem.Selected="TreeViewItem_Selected"/>

Then in your control.xaml.cs code behind, you can grab that selected TreeViewItem from the RoutedEventArgs and set it to IsExpanded:

private void TreeViewItem_Selected(object sender, RoutedEventArgs e)
{
    TreeViewItem tvi = e.OriginalSource as TreeViewItem;

    if (tvi == null || e.Handled) return;

    tvi.IsExpanded = !tvi.IsExpanded;
    e.Handled = true;
}

Nice and clean. Hopefully that helps someone!

Tags:

Wpf

Treeview