gpt4 book ai didi

c# - 通过 DataTrigger 在 WPF TreeViewItem 上设置 IsExpanded

转载 作者:太空狗 更新时间:2023-10-29 20:07:41 26 4
gpt4 key购买 nike

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

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

如何从 DataTrigger 设置 TreeViewItem.IsExpanded 属性?

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

Screenshot just after starting the application

并且在改变_myItems[0].MyStatus_myItems[1].MyStatus的值后,颜色也随之改变,但绿色节点仍然没有展开。

Screenshot after clicking the Button1

完整代码 (XAML)

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

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

完整代码(C#)

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;

namespace WpfApplication6
{
public partial class MainWindow : Window
{
private ObservableCollection<MyItemCollection> _myItems;

public MainWindow() {
InitializeComponent();

_myItems = new ObservableCollection<MyItemCollection> {
new MyItemCollection { Name = "Parent1", MyStatus = MyStatus.Closed, SubItems = { new MyItemCollection { Name = "Child1" } } },
new MyItemCollection { Name = "Parent2", MyStatus = MyStatus.Opened, SubItems = { new MyItemCollection { Name = "Child2" } } }
};

DataContext = new {
MyItems = _myItems
};
}

private void button1_Click(object sender, RoutedEventArgs e) {
_myItems[0].MyStatus = MyStatus.Opened;
_myItems[1].MyStatus = MyStatus.Closed;
}
}

public enum MyStatus
{
Closed,
Opened
}

public class MyItemCollection : INotifyPropertyChanged
{
public MyItemCollection() {
SubItems = new ObservableCollection<MyItemCollection>();
_myStatus = MyStatus.Closed;
}

public string Name { get; set; }

public ObservableCollection<MyItemCollection> SubItems { get; set; }

private MyStatus _myStatus;
public MyStatus MyStatus {
get { return _myStatus; }
set { _myStatus = value; NotifyPropertyChanged("MyStatus"); }
}

public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName) {
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) {
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}

最佳答案

这里有一些错误。第一个是您在 HierarchicalDataTemplate 上设置属性 TreeViewItem.IsSelected。这行不通。相反,您需要在 TreeView 上设置一个 ItemContainerStyle:

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

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

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

关于c# - 通过 DataTrigger 在 WPF TreeViewItem 上设置 IsExpanded,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18403929/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com