Disable focus of some records in TreeView

I have a TreeView that is populated with various types of elements. Elements can be of type Node(then they can have children) or type Entry(then they have no children). To do this, I bound my TreeView to the ViewModel property AllNodesAndEntries, which is ObservableCollection<object>. For different types Node, EntryI also defined two DataTemplates. Here is the code:

<TreeView ItemsSource="{Binding AllNodesAndEntries}">
    <TreeView.Resources>
        <HierarchicalDataTemplate ItemsSource="{Binding Children}"
                                  DataType="{x:Type local:Node}">
            <TextBlock Text="{Binding Name}"
                       Background="LightBlue"/>
        </HierarchicalDataTemplate>
        <DataTemplate DataType="{x:Type local:Entry}">
            <TextBlock Text="{Binding Name}"
                       Background="LightSalmon"/>
        </DataTemplate>
    </TreeView.Resources>
</TreeView>

Now I want to make the elements Entryunmanageable if a certain condition is met (that is, if my ViewModel property MyPropis equal true).

So, I added a trigger to the DataTemplate for Entryas follows:

        <DataTemplate DataType="{x:Type local:Entry}">
            <TextBlock Text="{Binding Name}"
                       Background="LightSalmon"/>
            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding MyProp}" Value="True">
                    <Setter Property="Focusable" Value="False"/>
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>

, , MyProp true. ? ?

a NotifyPropertyChanged(nameof(MyProp)); MyProp, MyProp .

+4
3

IsNodeConverter, , MultiDataTrigger, :

  • ViewModel MyProp= true
  • TreeViewItem Entry

XAML

<Window.Resources>
    <local:IsNodeConverter x:Key="IsNodeConverter"/>
</Window.Resources>

...

    <TreeView ItemsSource="{Binding AllNodesAndEntries}">
        <TreeView.Resources>

            ...

        </TreeView.Resources>
        <TreeView.ItemContainerStyle>
            <Style TargetType="{x:Type TreeViewItem}">
                <Style.Triggers>
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition  Binding="{Binding DataContext.MyProp, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
                                        Value="True"/>
                            <Condition  Binding="{Binding Converter={StaticResource IsNodeConverter}}"
                                        Value="False"/>
                        </MultiDataTrigger.Conditions>
                        <MultiDataTrigger.Setters>
                            <Setter Property="Focusable" Value="False"></Setter>
                        </MultiDataTrigger.Setters>
                    </MultiDataTrigger>
                </Style.Triggers>
            </Style>
        </TreeView.ItemContainerStyle>
    </TreeView>
+4

, Focusable DataTemplate, TreeViewItem.

TreeViewItem :

    <TreeView ItemsSource="{Binding Items}">
        <TreeView.ItemContainerStyle>
            <Style TargetType="{x:Type TreeViewItem}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding MyProp}"
                                 Value="True">
                        <Setter Property="Focusable"
                                Value="False" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </TreeView.ItemContainerStyle>
    </TreeView>
+2

This is not a problem, you just need to set the property Focusablein TreeViewItem. Just add the following to TreeView.Resources:

<TreeView.Resources>
    <DataTemplate DataType="{x:Type local:Entry}">
        <TextBlock Text="{Binding Name}" Background="LightSalmon"/>
    </DataTemplate>
    <Style TargetType="TreeViewItem">
        <Style.Triggers>
            <DataTrigger Binding="{Binding MyProp}" Value="True">
                <Setter Property="Focusable" Value="False" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
</TreeView.Resources>

This style now happens on all of your TreeViewItems. If you want to prevent the use of this style Nodes, you can do it in code or just bind your element objectand use Converter.

0
source

Source: https://habr.com/ru/post/1657079/


All Articles