gpt4 book ai didi

c# - 在 WPF 中,如何以编程方式取消选择 TreeView 中的所有项目?

转载 作者:行者123 更新时间:2023-12-02 01:59:20 24 4
gpt4 key购买 nike

我正在尝试创建一个递归方法来取消选择 WPF TreeView 中的所有项目。让事情变得复杂的是每个 TreeViewItem 都不是一个迷你 TreeView。这导致您必须来回进行大量转换。所以,这是我尝试过的:

TreeViewDeselectAll(myTreeView.Items);      

// Must send in ItemCollection to allow the recursive call
private void TreeViewDeselectAll(ItemCollection myTreeViewItems)
{
// The only way to get to the IsSelected property is to turn it back into a TreeViewItem
foreach (TreeViewItem currentItem in myTreeViewItems)
{
currentItem.IsSelected = false;
if (currentItem.HasItems)
{
// Recursify!
TreeViewDeselectAll(currentItem.Items);
}
}
}

有人成功取消选择 TreeView 中的所有项目吗?您是否能够以递归方式遍历 TreeView?

Winforms TreeView 有一个 Nodes 集合,它实际上是一个迷你 TreeView。这允许递归就好了。但 WPF TreeView 没有节点。

使用 .Net 4.0 工作。

最佳答案

好的。删除所有代码并重新开始。

如果您正在使用 WPF,您确实需要抛弃恐龙技术(例如 winforms)中的所有过时实践,并理解并拥抱 The WPF Mentality

在 WPF 中,您不能以编程方式“选择 TreeViewItem”,仅仅是因为 UI is Not Data

UI 不负责跟踪显示在 TreeView 或任何其他 UI 元素中的数据项的选择状态。

相反,您可以创建一个适当的 DataModel 和一个 ViewModel 来分别保存数据和应用程序逻辑。

article 有一篇非常有趣的 Josh Smith 文章,解释了如何以正确的方式处理 WPF 中的 TreeView。

基本上是这样的:

<Window x:Class="MiscSamples.MVVMTreeViewSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MVVMTreeViewSample" Height="300" Width="300">
<DockPanel>
<Button Content="Select All" Click="SelectAll" DockPanel.Dock="Top"/>
<Button Content="Select None" Click="SelectNone" DockPanel.Dock="Top"/>

<TreeView ItemsSource="{Binding}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<CheckBox IsChecked="{Binding IsSelected}" Content="{Binding DisplayName}"/>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</DockPanel>
</Window>

背后代码:

public partial class MVVMTreeViewSample : Window
{
private ObservableCollection<HierarchicalData> Data;

public MVVMTreeViewSample()
{
InitializeComponent();
DataContext = Data = CreateData();
}

private void Select(IEnumerable<HierarchicalData> items, bool isselected)
{
while (items.Any())
{
items.ToList().ForEach(x => x.IsSelected = isselected);
items = items.SelectMany(x => x.Children);
}
}

private void SelectAll(object sender, RoutedEventArgs e)
{
Select(Data, true);
}

private void SelectNone(object sender, RoutedEventArgs e)
{
Select(Data, false);
}

private ObservableCollection<HierarchicalData> CreateData()
{
return new ObservableCollection<HierarchicalData>
{
//... Dummy Data here
}
}
}

数据项:

public class HierarchicalData : System.ComponentModel.INotifyPropertyChanged
{

public string DisplayName { get; set; }

private bool _isSelected;
public bool IsSelected
{
get { return _isSelected; }
set
{
_isSelected = value;
OnPropertyChanged("IsSelected");
}
}

public ObservableCollection<HierarchicalData> Children { get; private set; }

public HierarchicalData()
{
Children = new ObservableCollection<HierarchicalData>();
}

public event PropertyChangedEventHandler PropertyChanged;

protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}

结果:

enter image description here

  • 看看为什么没有一行代码可以操作任何 UI 元素。一切都是通过 DataBinding 到 Simple、Simple Properties 和 INotifyPropertyChanged 完成的。这就是在 WPF 中编程的方式。不需要复杂的 VisualTreeHelper.Whatever() 东西,不需要复杂的操作,因为 UI 虚拟化等会导致各种问题。
  • SelectAll()SelectNone() 方法中,我只是迭代 Data Items 而不是 UI 元素,并设置他们的值(value)观相应。然后,WPF 通过 DataBinding 引擎更新 UI。
  • 了解如何无需将任何内容转换为任何内容,以及如何使用自己的简单类,而不必处理复杂、神秘的 WPF 对象模型。
  • 忘记 winform。它是一只无用的恐龙,不支持任何东西。
  • WPF 岩石。只需将我的代码复制并粘贴到文件 -> 新项目 -> WPF 应用程序 中即可亲自查看结果。请注意,您需要使用 CreateData() 方法将项目添加到集合中。
  • 如果您需要进一步帮助,请告诉我。

关于c# - 在 WPF 中,如何以编程方式取消选择 TreeView 中的所有项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20707788/

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