Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable focusability of certain entries in TreeView

I have a TreeView that is filled with different types of items. The items can either be of type Node (then they may have children) or of type Entry (then they don't have children). For that, I bound my TreeView to my ViewModel property AllNodesAndEntries which is an ObservableCollection<object>. For different looks of Node and Entry I 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 Entry elements unfocusable if a certain condition is met (that is, if my ViewModel property MyProp is true).

So I added a trigger into the DataTemplate for Entry like this:

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

But it does not work, I can still select entries after MyProp was set to true. What am I doing wrong? How do I make it work?

I did put a NotifyPropertyChanged(nameof(MyProp)); in the setter of MyProp, so changes to MyProp will be reported to the View.

like image 491
Kjara Avatar asked Oct 07 '16 14:10

Kjara


1 Answers

Using the IsNodeConverter you've posted, you can implement a MultiDataTrigger that only fires when both conditions are fulfilled:

  • ViewModel MyProp = true
  • TreeViewItem of type 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>
like image 63
Funk Avatar answered Oct 17 '22 02:10

Funk