How to prevent selection of a TreeViewItem based on a condition

13.1k Views Asked by At

I have wpf TreeView -- bound to some data. The Treeview resides on the left hand of a window divided into two areas where the tree is the navigation and a panel on the right side changes content depending on the tree node selected.

Not all the nodes of the treeview produce detail information. I want to disable the selection of those nodes. Any idea?

Thanks

2

There are 2 best solutions below

5
On

Do you have something like a boolean property in your source called HasDetails or something? In that case you can use something like this. Create a MultiDataTrigger in the ItemContainerStyle that binds to HasDetails in the DataContext and IsSelected for the TreeViewItem and if both are True (well, True that HasDetails is False:-), you start a Storyboard that "unselects" the newly selected TreeViewItem.

This will disable selection for all the TreeViewItem's that doesn't have details but they will still be expandable. Hopefully that was what you were looking for

<TreeView ...>
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Style.Triggers>
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding HasDetails}" Value="False"/>
                        <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="True"/>
                    </MultiDataTrigger.Conditions>
                    <MultiDataTrigger.EnterActions>
                        <BeginStoryboard>
                            <Storyboard>
                                <BooleanAnimationUsingKeyFrames BeginTime="00:00:00"
                                                                Storyboard.TargetProperty="(TreeViewItem.IsSelected)">
                                    <DiscreteBooleanKeyFrame KeyTime="00:00:00" Value="False"/>
                                </BooleanAnimationUsingKeyFrames>
                            </Storyboard>
                        </BeginStoryboard>
                    </MultiDataTrigger.EnterActions>
                </MultiDataTrigger>
            </Style.Triggers>
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>

Update

To disable the TreeViewItem's where HasDetails is False you can use this

<TreeView ...>
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsEnabled" Value="{Binding HasDetails}"/>
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>
1
On

@jama64 : You can achieve what you want if you change the Style from Property IsEnabled to Focusable.

<TreeView.ItemContainerStyle>
     <Style TargetType="{x:Type TreeViewItem}">
         <Setter Property="Focusable" Value="{Binding HasDetails}"/>
     </Style>
</TreeView.ItemContainerStyle>