wpf 获取在树视图中选择的节点
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11981402/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get the nodes selected in treeview
提问by Ramesh Durai
I have a custom treeview class in WPF. I wanted to get the selected nodes text in a string list.
我在 WPF 中有一个自定义的树视图类。我想在字符串列表中获取选定的节点文本。
Rules:
规则:
- If all the nodes in parent is selected, then return the parent node text alone.
If all the nodes in parent is not selected, then return a list of
parentName_childNameof the nodes which is selected.The above two rules will apply for all levels. For a treeview with 2 levels of hierarchy return the name as
parentName_child1Name_child1ChildName.
- 如果父节点中的所有节点都被选中,则单独返回父节点文本。
如果未选择 parent 中的所有节点,则返回
parentName_childName所选节点的列表。以上两条规则适用于所有级别。对于具有 2 个层次结构的树视图,将名称返回为
parentName_child1Name_child1ChildName.
Node template c# code:
节点模板 c# 代码:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
namespace TreeViewCheckBox
{
public struct CheckBoxId
{
public static string IDCheckBox;
}
public class Node : INotifyPropertyChanged
{
private readonly ObservableCollection<Node> children = new ObservableCollection<Node>();
private readonly ObservableCollection<Node> parent = new ObservableCollection<Node>();
private bool? isChecked = true;
private bool isExpanded;
private string text;
public Node()
{
this.Id = Guid.NewGuid().ToString();
}
public event PropertyChangedEventHandler PropertyChanged;
public ObservableCollection<Node> Children
{
get { return this.children; }
}
public string Id { get; set; }
public bool? IsChecked
{
get { return this.isChecked; }
set
{
this.isChecked = value;
this.RaisePropertyChanged("IsChecked");
}
}
public bool IsExpanded
{
get { return this.isExpanded; }
set
{
this.isExpanded = value;
this.RaisePropertyChanged("IsExpanded");
}
}
public ObservableCollection<Node> Parent
{
get { return this.parent; }
}
public string Text
{
get { return this.text; }
set
{
this.text = value;
this.RaisePropertyChanged("Text");
}
}
private void CheckedTreeChild(IEnumerable<Node> items, int countCheck)
{
bool isNull = false;
foreach (Node paren in items)
{
foreach (Node child in paren.Children)
{
if (child.IsChecked == true || child.IsChecked == null)
{
countCheck++;
if (child.IsChecked == null)
{
isNull = true;
}
}
}
if (countCheck != paren.Children.Count && countCheck != 0)
{
paren.IsChecked = null;
}
else if (countCheck == 0)
{
paren.IsChecked = false;
}
else if (countCheck == paren.Children.Count && isNull)
{
paren.IsChecked = null;
}
else if (countCheck == paren.Children.Count && !isNull)
{
paren.IsChecked = true;
}
if (paren.Parent.Count != 0)
{
this.CheckedTreeChild(paren.Parent, 0);
}
}
}
private void CheckedTreeChildMiddle(
IEnumerable<Node> itemsParent, IEnumerable<Node> itemsChild, bool? isCheckBoxChecked)
{
const int CountCheck = 0;
this.CheckedTreeParent(itemsChild, isCheckBoxChecked);
this.CheckedTreeChild(itemsParent, CountCheck);
}
private void CheckedTreeParent(IEnumerable<Node> items, bool? isCheckBoxChecked)
{
foreach (Node item in items)
{
item.IsChecked = isCheckBoxChecked;
if (item.Children.Count != 0)
{
this.CheckedTreeParent(item.Children, isCheckBoxChecked);
}
}
}
private void RaisePropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
const int CountCheck = 0;
if (propertyName == "IsChecked")
{
if (this.Id == CheckBoxId.IDCheckBox && this.Parent.Count == 0 && this.Children.Count != 0)
{
this.CheckedTreeParent(this.Children, this.IsChecked);
}
if (this.Id == CheckBoxId.IDCheckBox && this.Parent.Count > 0 && this.Children.Count > 0)
{
this.CheckedTreeChildMiddle(this.Parent, this.Children, this.IsChecked);
}
if (this.Id == CheckBoxId.IDCheckBox && this.Parent.Count > 0 && this.Children.Count == 0)
{
this.CheckedTreeChild(this.Parent, CountCheck);
}
}
}
}
}
UserControl XAML code:
用户控件 XAML 代码:
<UserControl x:Class="TreeViewCheckBox.CustomTreeView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:TreeViewWithImageCheckBox="clr-namespace:TreeViewCheckBox"
mc:Ignorable="d">
<UserControl.Resources>
<HierarchicalDataTemplate DataType="{x:Type TreeViewCheckBox:Node}" ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<StackPanel.Margin>2</StackPanel.Margin>
<CheckBox Margin="1" IsChecked="{Binding IsChecked}"
PreviewMouseLeftButtonDown="CheckBox_PreviewMouseLeftButtonDown"
Uid="{Binding Id}" />
<TextBlock Margin="1" Text="{Binding Text}" />
</StackPanel>
</HierarchicalDataTemplate>
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="{Binding Path=IsExpanded, Mode=TwoWay}" />
</Style>
</UserControl.Resources>
<Grid>
<TreeView Name="tvMain" Grid.ColumnSpan="2" x:FieldModifier="private" />
</Grid>
</UserControl>
UserControl c# code:
用户控件 C# 代码:
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq;
using System.Windows.Controls;
namespace TreeViewCheckBox
{
public partial class CustomTreeView
{
public CustomTreeView()
{
this.Nodes = new ObservableCollection<Node>();
this.InitializeComponent();
this.FillTree();
}
private ObservableCollection<Node> Nodes { get; set; }
public void FillTree()
{
this.Nodes.Clear();
for (int i = 0; i < 5; i++)
{
var level1Items = new Node { Text = " Level 1 Item " + (i + 1) };
for (int j = 0; j < 2; j++)
{
var level2Items = new Node { Text = " Level 2 Item " + (j + 1) };
level2Items.Parent.Add(level1Items);
level1Items.Children.Add(level2Items);
for (int n = 0; n < 2; n++)
{
var level3Items = new Node { Text = " Level 3 Item " + (n + 1) };
level3Items.Parent.Add(level2Items);
level2Items.Children.Add(level3Items);
}
}
this.Nodes.Add(level1Items);
}
this.tvMain.ItemsSource = this.Nodes;
}
private void CheckBox_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
var currentCheckBox = (CheckBox)sender;
CheckBoxId.IDCheckBox = currentCheckBox.Uid;
}
}
}
How to get the selected nodes in a List?
如何获取列表中的选定节点?
采纳答案by Sandeep
Probably, you will have to traverse through the Nodes collection and check for value of the IsChecked property. Something like this:
您可能需要遍历 Nodes 集合并检查 IsChecked 属性的值。像这样的东西:
private List<string> SelectedNodes = new List<string>();
private void GetSelectedNodeText(NodeCollection nodes)
{
foreach (Node node in nodes)
{
if (node.IsChecked != true && node.IsChecked != false)
{
SelectedNodes.Add(node.Text + "_" + GetSelectedChildNodeText(node.ChildNodes));
}
else if (node.IsChecked == true)
{
SelectedNodes.Add(node.Text);
}
}
}
private string GetSelectedChildNodeText(NodeCollection nodes)
{
string retValue = string.Empty;
foreach (Node node in nodes)
{
if (node.IsChecked != true && node.IsChecked != false)
{
retValue = node.Text + "_" + GetSelectedChildNodeText(node.ChildNodes);
}
else if (node.IsChecked == true)
{
retValue = node.Text;
}
}
return retVal;
}
My assumptions:
我的假设:
- The IsChecked property has true value when all it's children are selected.
- The IsChecked property has false value when all it's children are de-selected.
- The IsChecked property has neither true nor false value when only some of it's children are selected.
- You have the node's Text in the Node.Text property.
- IsChecked 属性在它的所有子项都被选中时具有真值。
- 当取消选择所有子项时,IsChecked 属性具有 false 值。
- 当仅选择了 IsChecked 的某些子项时,IsChecked 属性既没有 true 也没有 false 值。
- 您在 Node.Text 属性中有节点的文本。
回答by Ramesh Durai
Thanks to Sandeep for his idea.
感谢 Sandeep 的想法。
The following code is working fine..
以下代码工作正常..
public List<string> GetSelectedNodes()
{
var listNodes = new List<string>();
foreach (Node node in this.Nodes)
{
if (node.IsChecked == null)
{
this.GetSelectedChildNodeText(node.Text, node.Children, ref listNodes);
}
else if (node.IsChecked == true)
{
listNodes.Add(node.Text);
}
}
return listNodes;
}
private void GetSelectedChildNodeText(string nodeName, IEnumerable<Node> nodes, ref List<string> listNodes)
{
foreach (Node node in nodes)
{
string currentName = string.Format("{0}_{1}", nodeName, node.Text);
if (node.IsChecked == null)
{
this.GetSelectedChildNodeText(currentName, node.Children, ref listNodes);
}
else if (node.IsChecked == true)
{
listNodes.Add(currentName);
}
}
}

