从DataTrigger在WPF TreeViewItem上设置IsExpanded

时间:2013-08-23 13:20:44

标签: c# wpf xaml treeview treeviewitem

我正在尝试使用条件模板在IsExpanded中设置TreeView项的XAML属性:

<DataTrigger Binding="{Binding MyStatus}" Value="Opened">
    <Setter TargetName="MyTextBlock" Property="Foreground" Value="Green"/>
    <Setter Property="TreeViewItem.IsExpanded" Value="True" />
</DataTrigger>

当我从C#代码设置MyStatus属性时,颜色会发生变化(因此DataTrigger会起作用),但节点不会展开。

_myItems[0].MyStatus = MyStatus.Opened;

如何设置TreeViewItem.IsExpanded的{​​{1}}属性?

启动应用程序时,颜色设置正确,但绿色节点未展开:

Screenshot just after starting the application

更改DataTrigger_myItems[0].MyStatus的值后,颜色会相应更改,但绿色节点仍未展开。

Screenshot after clicking the Button1

完整代码(XAML)

完整的代码有点长,但它是90%的样板。

_myItems[1].MyStatus

完整代码(C#)

<Window x:Class="WpfApplication6.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="150" Width="250">
    <DockPanel>
        <DockPanel.Resources>
            <HierarchicalDataTemplate ItemsSource="{Binding SubItems}" x:Key="MyTemplate">
                <StackPanel Orientation="Horizontal">
                    <!-- ... -->
                    <TextBlock x:Name="MyTextBlock" Foreground="Green" Text="{Binding Name}" />
                </StackPanel>

                <HierarchicalDataTemplate.Triggers>
                    <DataTrigger Binding="{Binding MyStatus}" Value="Closed">
                        <Setter TargetName="MyTextBlock" Property="Foreground" Value="Red"/>
                        <Setter Property="TreeViewItem.IsExpanded" Value="False" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding MyStatus}" Value="Opened">
                        <Setter TargetName="MyTextBlock" Property="Foreground" Value="Green"/>
                        <Setter Property="TreeViewItem.IsExpanded" Value="True" />
                    </DataTrigger>
                </HierarchicalDataTemplate.Triggers>
            </HierarchicalDataTemplate>
        </DockPanel.Resources>

        <Button Name="button1" Click="button1_Click" DockPanel.Dock="Top" Content="Button1"/>
        <TreeView Name="treeView1" ItemsSource="{Binding MyItems}" ItemTemplate="{StaticResource MyTemplate}"/>
    </DockPanel>
</Window>

2 个答案:

答案 0 :(得分:9)

这里有一些问题。首先,您要在TreeViewItem.IsSelected上设置属性HierarchicalDataTemplate。这不行。相反,您需要在ItemContainerStyle上设置TreeView

<TreeView>
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
        <!-- put logic for handling expansion here -->
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>

但是,您不能只将Trigger放在这里。由于DependencyProperty value precedence,如果您的用户单击节点以展开或折叠它们,则您的触发器将不会是优先级列表上的#1(即本地值)。因此,您最好的办法是创建一个新的IValueConverter,以便从MyStatus转换为bool。然后在TwoWay中的Setter中设置Style绑定:

<Style TargetType="{x:Type TreeViewItem}">
    <Setter Property="IsExpanded" 
            Value="{Binding MyStatus, Converter={StaticResource statusToBool}}" />
</Style>

你的转换器:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    return ((MyStatus)value) == MyStatus.Opened;
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
    return ((bool)value) ? MyStatus.Opened : MyStatus.Closed;
}

答案 1 :(得分:1)

我必须做类似的事情,我这样解决了:

<TreeView ItemsSource="{Binding source}"
          SnapsToDevicePixels="{Binding Path=myStatusToBool}"
          >
  <TreeView.ItemContainerStyle>
    <Style>
      <Setter Property="TreeViewItem.IsExpanded"
              Value="False"
              />
      <Style.Triggers>
        <DataTrigger Binding="{Binding Path=SnapsToDevicePixels,RelativeSource={RelativeSource AncestorType=TreeView}}"
                     Value="True">
            <Setter Property="TreeViewItem.IsExpanded"
                    Value="True"
                    />
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </TreeView.ItemContainerStyle>

  <TreeView.Resources>
  .....
  .....
  </TreeView.Resources>
</TreeView>