一、目的:在绑定TreeView的功能中经常会遇到需要在树节点前增加勾选CheckBox框,勾选本节点的同时也要同步显示父节点和子节点状态
二、实现
三、环境
VS2022
四、示例
定义如下节点类
public partial class TreeNodeBase<T> : SelectBindable<T>, ITreeNode
{
public TreeNodeBase(T t) : base(t)
{
}
private bool? _isChecked = false;
public bool? IsChecked
{
get { return _isChecked; }
set
{
_isChecked = value;
RaisePropertyChanged();
RefreshParentCheckState();
RefreshChildrenCheckState();
}
}
private void RefreshParentCheckState()
{
if (Parent == null)
return;
bool allChecked = Parent.Nodes.All(l => l.IsChecked == true);
if (allChecked)
{
Parent.CheckOnlyCurrent(true);
Parent.RefreshParentCheckState();
return;
}
bool allUnChecked = Parent.Nodes.All(l => l.IsChecked == false);
if (allUnChecked)
{
Parent.CheckOnlyCurrent(false);
Parent.RefreshParentCheckState();
return;
}
Parent.CheckOnlyCurrent(null);
Parent.RefreshParentCheckState();
}
private void RefreshChildrenCheckState()
{
foreach (TreeNodeBase<T> item in Nodes)
{
item.CheckOnlyCurrent(IsChecked);
item.RefreshChildrenCheckState();
}
}
private void CheckOnlyCurrent(bool? value)
{
_isChecked = value;
RaisePropertyChanged("IsChecked");
}
public TreeNodeBase<T> Parent { get; set; }
private ObservableCollection<TreeNodeBase<T>> _nodes = new ObservableCollection<TreeNodeBase<T>>();
public ObservableCollection<TreeNodeBase<T>> Nodes
{
get { return _nodes; }
set
{
_nodes = value;
RaisePropertyChanged();
}
}
public void AddNode(TreeNodeBase<T> node)
{
node.Parent = this;
Nodes.Add(node);
}
}
其中核心方法是如下方法
分别在当前节点勾选有变化时去更新父节点和子节点的勾选状态
五、需要了解的知识点
TreeView 类 (System.Windows.Controls) | Microsoft Learn
六、源码地址
GitHub - HeBianGu/WPF-ControlDemo: 示例
GitHub - HeBianGu/WPF-ControlBase: Wpf封装的自定义控件资源库
GitHub - HeBianGu/WPF-Control: WPF轻量控件和皮肤库