我在WPF中有一个自定义的treeview类。 我想在字符串列表中获取所选节点文本。
规则:
如果未选择父级中的所有节点,则返回所选节点的parentName_childName
列表。
以上两条规则适用于所有级别。对于具有2级层次结构的树视图,将名称返回为parentName_child1Name_child1ChildName
。
节点模板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代码:
<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:
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;
}
}
}
如何在列表中获取所选节点?
答案 0 :(得分:1)
可能您必须遍历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;
}
我的假设:
答案 1 :(得分:0)
感谢Sandeep的想法。
以下代码工作正常..
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);
}
}
}