如何根据条件防止选择 TreeViewItem

10
我有一个绑定了数据的WPF TreeView。 TreeView位于窗口左侧,窗口被分为两个区域,其中树是导航,右侧面板根据选定的节点更改内容。
并非所有树节点都会产生详细信息。我想禁用那些节点的选择。有什么想法吗?
谢谢

2
为什么不直接显示一个像“没有可用的详细信息”这样的消息,而选择使它们无法选择并不符合TreeView的功能。如果用户单击一个节点,但该节点未被选中,他的第一个想法将是点击丢失了(没有其操作的视觉反馈)。更不用说实现起来要容易得多了。 - Andrei Pana
2个回答

22

@jama64:如果你将样式从“IsEnabled”更改为“Focusable”,就可以实现你想要的效果。

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

如果您想禁用鼠标悬停时的高亮,请使用以下内容:<Style TargetType="TreeViewItem"> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"/> </Style.Triggers> <Setter Property="Focusable" Value="False" /> </Style> - Luke Vanzweden

5
你的源代码中是否有类似于布尔属性的东西,名称为HasDetails或类似的内容?如果是这样,你可以使用以下方法。在ItemContainerStyle中创建一个MultiDataTrigger,将其绑定到DataContext中的HasDetailsTreeViewItemIsSelected,如果两者都为True(当HasDetails为False时为True:-),则开始一个Storyboard来“取消选择”新选择的TreeViewItem

这将禁用所有没有详细信息的TreeViewItem的选择,但它们仍然可以展开。希望这正是你想要的。

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

更新

如果要禁用TreeViewItem中的HasDetails为False的部分,可以使用以下代码:

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

谢谢Meleak。它运行得非常好,但是我失去了最后一个节点的选择高亮。有什么想法吗? - jama64
@jama64:你的意思是说你可以选择它,但它没有高亮显示(改变颜色)吗?如果是这样,我无法复现它。 - Fredrik Hedblad
不,它不会按需选择,而是整个树都会失去选择高亮显示。例如,如果有一个可选择的节点处于活动状态,并且我们尝试选择一个不可选择的节点,那么该不可选择的节点将不会被选中,但随后整个树都会失去选择高亮显示。 - jama64
1
@jama64:没有详细信息的节点必须可展开吗?否则,您可以使用IsEnabled。将TreeView重置为上次选择的项需要一些代码,但如果您愿意,我可以发布它。 - Fredrik Hedblad
Meleak,是的,没有详细信息的节点需要展开和折叠。它们包含具有详细信息的节点。 - jama64

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接