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

我正在尝试创建一个递归方法来取消选择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中工作。

每个TreeViewItem都是一个Mini-TreeView。 你得到了错误的印象或者你读错了TreeViewItems。

你做错了是传递Items集合,它不包含TreeViewItem类型的子节点,而是那些是数据项。

通过儿童collections,你应该做得很好。

像这样:

 public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private bool @switch = false; private void TreeViewDeselectAll(IEnumerable myTreeViewItems, bool value) { if (myTreeViewItems != null) { foreach (var currentItem in myTreeViewItems) { if (currentItem is TreeViewItem) { TreeViewItem item = (TreeViewItem)currentItem; item.IsSelected = value; if (item.HasItems) { TreeViewDeselectAll(LogicalTreeHelper.GetChildren(item), value); } } } } } private void Button_Click(object sender, RoutedEventArgs e) { this.TreeViewDeselectAll(LogicalTreeHelper.GetChildren(this.treeView), this.@switch); } } 

例如,XAML看起来像这样:

         

我稍微更改了TreeViewDeselectAll方法。 根据开关,您可以选择或取消全选。

好。 删除所有代码并从头开始。

如果你正在使用WPF,你真的需要抛弃恐龙技术(如winforms)的所有古老实践,并理解和拥抱WPF心态

在WPF中,您不是以编程方式“选择TreeViewItem”,因为UI不是数据

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

而是分别创建一个适当的DataModel和一个ViewModel来保存数据和应用程序逻辑。

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

基本上是这样的:

              

代码背后:

 public partial class MVVMTreeViewSample : Window { private ObservableCollection Data; public MVVMTreeViewSample() { InitializeComponent(); DataContext = Data = CreateData(); } private void Select(IEnumerable 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 CreateData() { return new ObservableCollection { //... 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 Children { get; private set; } public HierarchicalData() { Children = new ObservableCollection(); } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); } } 

结果:

在此处输入图像描述

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