在MVVM的树节点中设置条件文本

时间:2019-01-23 15:03:47

标签: wpf xaml mvvm treeview

我有一个树节点,其文本设置如下。 Title属性是我的自定义类中代表树节点的属性。我的ViewModel存储了这些项目的ObservableCollection。

在某些情况下,我想绑定到除Title以外的其他属性。该条件将基于我所包含的ViewModel中的布尔属性,而不是自定义的treenode表示对象。

    <TreeView Name="OrganizationTree" SelectedItemChanged="OrganizationTree_OnSelectedItemChanged" ItemsSource="{Binding OrganizationTreeNodes}"
              ItemContainerStyle="{StaticResource ExpansionAndSelectionManagementStyle}">            
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding Title}" Style="{StaticResource NodeFontStyle}"/>
                </StackPanel>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>

我知道使用样式触发器来不同地样式化树。但是,样式触发器似乎只能取消树节点对象中的属性,而不是ViewModel。这是有道理的,因为您在每个节点上做事。

是否可以使用触发器或其他机制更改树节点的文本?

例如:

if (viewModel.IsShowingExtraData) 
{
   // use CustomTreeNodeObject's TitleAndExtra property
} 
else 
{
   // use CustomTreeNodeObject's Title property
}

我尝试过的事情:

我创建了一种新样式并将其应用于TextBlock。我设置了查找祖先来访问VM的属性。那行得通,但是我想让setter属性在树节点中使用一个属性。我不知道该如何“寻找后代”,而不是坚持父代的数据上下文。

    <Style x:Key="NodeTextConditionStyle" TargetType="TextBlock">
        <Setter Property="Text" Value="??"/>
        <Style.Triggers>
            <!-- note: the binding path is relative to an OrganizationTreeNode, not the view model. So need to do some relative ancestor trickery -->
            <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}, Path=DataContext.ShowOrganizationTypeDetails, UpdateSourceTrigger=PropertyChanged}" Value="True">
                <Setter Property="Text" Value="?? how to get descendant prop?"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}, Path=DataContext.ShowOrganizationTypeDetails, UpdateSourceTrigger=PropertyChanged}" Value="False">
                <Setter Property="Text" Value="?? how to get descendant prop?" />
            </DataTrigger>
        </Style.Triggers>
    </Style>

1 个答案:

答案 0 :(得分:0)

在我编辑的问题结尾处的尝试基本上在那里。我一定有错别字。 RelativeSource不会“滴灌”到XAML中的子节点。我能够返回标签中树节点对象的默认来源,并且可以正常工作:

<Style x:Key="NodeTextConditionStyle" TargetType="TextBlock">
    <Setter Property="Text" Value="??"/>
    <Style.Triggers>
        <!-- note: the binding path is relative to an OrganizationTreeNode, not the view model. So need to do some relative ancestor trickery -->
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}, Path=DataContext.ShowOrganizationTypeDetails, UpdateSourceTrigger=PropertyChanged}" Value="True">
            <Setter Property="Text" Value="{Binding TitleWithDetails}" />
        </DataTrigger>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}, Path=DataContext.ShowOrganizationTypeDetails, UpdateSourceTrigger=PropertyChanged}" Value="False">
            <Setter Property="Text" Value="{Binding Title}" />
        </DataTrigger>
    </Style.Triggers>
</Style>