How to make TreeView node selected / extended when ItemsSource = collection of custom objects?

I have TreeViewdesigned to work on two levels. For him, I have two HierarchicalDataTemplateand two user types. ItemsSourceconnected to ObservableCollectionand everything works fine. I just can't figure out how to make node selected or extended from codebehind. Somewhere was mentioned a good idea to attach the properties IsExpandedand IsSelectedto the corresponding properties in my custom types. The only problem is that it HierarchicalDataTemplatedoes not implement TreeViewItemdirectly, so how can I access these properties in the following code?

<TreeView Name="treeViewNotes" AllowDrop="True" PreviewMouseLeftButtonDown="treeViewNotes_PreviewMouseLeftButtonDown" PreviewMouseMove="treeViewNotes_PreviewMouseMove" Drop="treeViewNotes_Drop" DragEnter="treeViewNotes_DragEnter">
    <TreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type dataclasses:NoteFolder}" ItemsSource="{Binding Notes}">
            <StackPanel Orientation="Horizontal">
                <Image Height="16" Source="{Binding TreeViewIcon}" Tag="{Binding Self}"/>
                <TextBlock Text="{Binding Title}" Tag="{Binding Self}" Margin="3"/>
            </StackPanel>
        </HierarchicalDataTemplate>
        <HierarchicalDataTemplate DataType="{x:Type dataclasses:Note}">
            <StackPanel Orientation="Horizontal">
                <Image Height="16" Source="{Binding TreeViewIcon}" Tag="{Binding Self}"/>
                <TextBlock Text="{Binding Title}" Tag="{Binding Self}" Margin="3"/>
            </StackPanel>
        </HierarchicalDataTemplate>
    </TreeView.Resources>
</TreeView>

- Note NoteFolder, Note Folder . .

+4
3

TreeView ItemContainerStyle , IsExpanded IsSelected DataContext IsExpanded IsSelected:

<TreeView x:Name="..." ItemsSource="{Binding RootNode}">
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <!-- Items in the ItemsSource need to have these properties for the binding to work -->
            <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
            <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
            <!-- You can also optionally change some style values based on IsSelected and IsExpanded values -->
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsSelected}" Value="True">
                    <Setter Property="BorderThickness" Value="4 0 0 1"/>
                    <Setter Property="BorderBrush" Value="DeepSkyBlue"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding IsSelected}" Value="False">
                    <Setter Property="BorderThickness" Value="4 0 0 1 "/>
                    <Setter Property="BorderBrush" Value="Transparent"/>
                </DataTrigger>
            </Style.Triggers>
         </Style>
     </TreeView.ItemContainerStyle>
     <TreeView.Resources>
        <HierarchicalDataTemplate>
             ...
        </HierarchicalDataTemplate>
     </TreeView.Resources>
</TreeView>

, , ItemSource , .

+7

, HierarchicalDataTemplate TreeViewItem , ?

TreeView.ItemContainerStyle:

<TreeView ItemTemplate="{StaticResource ResourceKey=treeViewDataTemplate}"
      ItemsSource="{Binding Data}"
      Name="trvTreeView">
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsSelected" Value="{Binding Path=IsSelected}" />
            <Setter Property="IsExpanded" Value="{Binding Path=IsExpanded}" />
            <EventSetter Event="Expanded" Handler="TreeViewItem_Expanded" />
            <EventSetter Event="Collapsed" Handler="TreeViewItem_Collapsed" />
            <EventSetter Event="PreviewMouseRightButtonDown" Handler="TreeViewItem_PreviewMouseRightButtonDown" />
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>

:

private void TreeViewItem_Expanded(object sender, RoutedEventArgs e)
{
    TreeViewItem treeViewItem = e.OriginalSource as TreeViewItem;
    if (treeViewItem != null)
    {
        BaseObjectExplorerNode baseObjectExplorerNode = treeViewItem.Header as BaseObjectExplorerNode;
        if (baseObjectExplorerNode != null)
        {
            baseObjectExplorerNode.IsExpanded = true;
        }
    }
}

private void TreeViewItem_Collapsed(object sender, RoutedEventArgs e)
{
    TreeViewItem treeViewItem = e.OriginalSource as TreeViewItem;
    if (treeViewItem != null)
    {
        BaseObjectExplorerNode baseObjectExplorerNode = treeViewItem.Header as BaseObjectExplorerNode;
        if (baseObjectExplorerNode != null)
        {
            baseObjectExplorerNode.IsExpanded = false;
        }
    }
}

, :

root.IsExpanded = true;
+1

I do not see any problems. You can do StyleSelectortwo Styleand bind to properties.

XAML:

<TreeView Name="treeViewNotes" AllowDrop="True" PreviewMouseLeftButtonDown="treeViewNotes_PreviewMouseLeftButtonDown" PreviewMouseMove="treeViewNotes_PreviewMouseMove" Drop="treeViewNotes_Drop" DragEnter="treeViewNotes_DragEnter">
    <TreeView.Resources>
        <!-- StyleSelector for containers -->
        <notdataclasses:NoteStyleSelector x:Key="NoteStyleSelector" />

        <!-- Style for a NoteFolder container -->
        <Style x:Key="NoteFolderStyle" TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsSelected" Value="{Binding Path=IsSelected}" />
            <Setter Property="IsExpanded" Value="{Binding Path=IsExpanded}" />
            <Setter Property="ItemContainerStyleSelector" Value="{StaticResource NoteFolderStyle}" />
        </Style>
        <!-- Style for a Note container -->
        <Style x:Key="NoteStyle" TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsSelected" Value="{Binding Path=IsSelected}" />
        </Style>

        <!-- ... -->
    </TreeView.Resources>
    <TreeView.ItemContainerStyleSelector>
        <StaticResource ResourceKey="NoteStyleSelector" />
    </TreeView.ItemContainerStyleSelector>
</TreeView>

NoteStyleSelector:

public sealed class NoteStyleSelector : StyleSelector
{
    public override Style SelectStyle(object item, DependencyObject container)
    {
        FrameworkElement fe = container as FrameworkElement;

        if (fe!= null)
        {
            if (item is Note)
            { return (Style)fe.FindResource("NoteStyle"); }

            if (item is NoteFolder)
            { return (Style)fe.FindResource("NoteFolderStyle"); }
        }

        return base.SelectStyle(item, container);
    }
}

In the drop handler:

currentFolder.Nodes.Add(pastedNode);

currentFolder.IsExpanded = true;
currentNode.IsSelected = true;

Cash desks:

public class Note : INotifyPropertyChanged
{
    // Only the IsSelected property because a Note can not be expanded
    public bool IsSelected { get { /* ... */ } set { /* ... */ } }
}

public class NoteFolder : INotifyPropertyChanged
{
    public bool IsSelected { get { /* ... */ } set { /* ... */ } }
    public bool IsExpanded { get { /* ... */ } set { /* ... */ } }
}
0
source

All Articles