根据视图模型数据设计包含多种类型的树的样式

时间:2018-09-27 20:43:58

标签: c# wpf mvvm treeview styling

我有一棵树,其中包含几种不同类型的项目。对于每种类型和出现在我的树中的项目,我已经达到了各自的视图模型。我有一个整体的TreeView.ItemContainerStyle,它执行绑定IsSelected和IsExpanded的基础,并且还将所选项目设置为粗体。

我现在正在尝试弄清我的不同类型(每种都有自己的HeirarchicalDataTemplate)如何根据关联的ViewModel中的数据设置文本样式的方法。

在这里尝试更好地解释是我的Tree的基础,它基本上具有Program的层次结构。任务|预算:

<TreeView ItemsSource="{Binding RootNodes}">
            <TreeView.ItemContainerStyle>
                <!--  This Style binds a TreeViewItem to a TreeViewItemViewModel.  -->
                <Style TargetType="{x:Type TreeViewItem}">
                    <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
                    <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
                    <Setter Property="FontWeight" Value="Normal" />
                    <Style.Triggers>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter Property="FontWeight" Value="Bold" />
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </TreeView.ItemContainerStyle>
            <TreeView.Resources>
                <HierarchicalDataTemplate DataType="{x:Type applayer:ProgrammeTreeViewModel}" ItemsSource="{Binding Children}" >
                    <StackPanel Orientation="Horizontal">
                        <!--Image Width="16" Height="16" Margin="3,0" Source="Images\Programme.png" / -->
                        <TextBlock Text="{Binding Programme.ProgrammeName}" />
                    </StackPanel>
                </HierarchicalDataTemplate>

                <HierarchicalDataTemplate DataType="{x:Type applayer:TaskTreeViewModel}" ItemsSource="{Binding Children}" >
                    <StackPanel Orientation="Horizontal">
                        <!--Image Width="16" Height="16" Margin="3,0" Source="Images\Task.png" / -->
                        <TextBlock Text="{Binding Task.Description}" />
                    </StackPanel>
                </HierarchicalDataTemplate>

                <DataTemplate DataType="{x:Type applayer:BudgetSummaryTreeViewModel}">
                    <StackPanel Orientation="Horizontal">
                        <!--Image Width="16" Height="16" Margin="3,0" Source="Images\Budget.png" / -->
                        <TextBlock Text="{Binding Budget.Description}" />
                    </StackPanel>
                </DataTemplate>
            </TreeView.Resources>
        </TreeView>

例如,现在我想做的是: 对于Program项,如果ProgrammeTreeViewModel IsStarted属性为true,则将文本设置为绿色,如果IsLate为true,则将文本设置为红色(优先于IsStarted为绿色)。

但是,对于Task,如果TaskTreeViewModel PeopleAssigned属性为true,则将文本完全设置为绿色,否则将其设置为红色。

类似地,我想使用Budget ViewModel的不同属性来设计Buget条目。

所有这些,同时保持整体加粗(如果选中)。

我确定我已经接近,并且我相信这应该相对容易-我刚刚在每个HeirarchicalDataTemplates中进行了实验,但到目前为止还没有乐趣。

任何帮助都将不胜感激!

1 个答案:

答案 0 :(得分:0)

正如问题注释中的@Aybe所述,只需为此使用触发器即可。

它看起来像这样:

<HierarchicalDataTemplate DataType="{x:Type applayer:ProgrammeTreeViewModel}" ItemsSource="{Binding Children}" >
    <StackPanel Orientation="Horizontal">
        <!--Image Width="16" Height="16" Margin="3,0" Source="Images\Programme.png" / -->
        <TextBlock x:Name="myText" Text="{Binding Programme.ProgrammeName}" />
    </StackPanel>
    <HierarchicalDataTemplate.Triggers>
        <DataTrigger Binding="{Binding IsStarted}" Value="True">
            <Setter TargetName="myText" Property="Foreground" Value="Green" />
        </DataTrigger>
        <DataTrigger Binding="{Binding IsLate}" Value="True">
            <Setter TargetName="myText" Property="Foreground" Value="Red" />
        </DataTrigger>
    </HierarchicalDataTemplate.Triggers>
</HierarchicalDataTemplate>

如果IsStartedIsLate都为true,则都将执行。 IsStarted的设置器将首先应用,然后IsLate的设置器将被应用。请牢记这一点很重要,因为如果您在前一个触发器中应用多个设置器,则会得到混合结果。要解决这个问题,您可能会使用MultiDataTrigger