wpf 中 带checkbox的treeview

时间:2023-01-12 19:37:04

(1)ModernCheckboxTree.xaml

<UserControl x:Class="FirstFloor.ModernUI.Windows.Controls.ModernCheckboxTree"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:FirstFloor.ModernUI.Model"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<DockPanel>
<Border DockPanel.Dock="Bottom">
<StackPanel Orientation="Horizontal" ToolTip="右键有更多功能哦!">
<!--<Image Height="16" Width="16" Source="Images/16_16/emoticon_smile.png"></Image>-->
<Label Content="右键有更多功能哦!" Foreground="Gray"></Label>
</StackPanel>
</Border>
<Border>
<TreeView Name="tvZsmTree">
<TreeView.ContextMenu>
<ContextMenu>
<MenuItem Name="menuExpandAll" Header="全部展开" Click="menuExpandAll_Click">
<!--<MenuItem.Icon>
<Image Source="Images/16_16/folder_open_arrow.png" />
</MenuItem.Icon>-->
</MenuItem>
<MenuItem Name="menuUnExpandAll" Header="全部折叠" Click="menuUnExpandAll_Click">
<!--<MenuItem.Icon>
<Image Source="Images/16_16/folder_close_arrow.png" />
</MenuItem.Icon>-->
</MenuItem>
<MenuItem Name="menuSelectAll" Header="全部选中" Click="menuSelectAll_Click">
<!--<MenuItem.Icon>
<Image Source="Images/16_16/tick.png" />
</MenuItem.Icon>-->
</MenuItem>
<MenuItem Name="menuUnSelectAll" Header="全部取消" Click="menuUnSelectAll_Click">
<!--<MenuItem.Icon>
<Image Source="Images/16_16/delete.png" />
</MenuItem.Icon>-->
</MenuItem>
</ContextMenu>
</TreeView.ContextMenu>
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"></Setter>
<EventSetter Event="TreeViewItem.PreviewMouseRightButtonDown" Handler="TreeViewItem_PreviewMouseRightButtonDown"/>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:TreeModel}" ItemsSource="{Binding Children}">
<StackPanel Margin="-2,0,0,0" Orientation="Horizontal" x:Name="staTree">
<CheckBox Click="menuSelectChanged" ToolTip="{Binding ToolTip}" Content="{Binding Name}" FontSize="14" FontFamily="微软雅黑" Tag="{Binding Children}" IsChecked="{Binding IsChecked, Mode=TwoWay}">
<!--<StackPanel Orientation="Horizontal">
<Image VerticalAlignment="Center" Source="{Binding Icon}" ></Image>
<TextBlock Text="2112sdddddddddd" ></TextBlock>
</StackPanel>-->
<CheckBox.ContextMenu>
<ContextMenu>
<MenuItem Name="menuSelectAllChild" Header="全部选中子项" Click="menuSelectAllChild_Click">
<!--<MenuItem.Icon>
<Image Source="Images/16_16/tick.png" />
</MenuItem.Icon>-->
</MenuItem>
</ContextMenu>
</CheckBox.ContextMenu>
</CheckBox>
</StackPanel>
<HierarchicalDataTemplate.Triggers>
<DataTrigger Binding="{Binding IsChecked}" Value="true">
<Setter TargetName="staTree" Property="Background" Value="White"/>
</DataTrigger>
</HierarchicalDataTemplate.Triggers>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Border>
</DockPanel>
</Grid>
</UserControl>


(2)ModernCheckboxTree.xaml.cs

using FirstFloor.ModernUI.Model;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace FirstFloor.ModernUI.Windows.Controls
{
/// <summary>
/// ModernCheckboxTree.xaml 的交互逻辑
/// </summary>
public partial class ModernCheckboxTree : UserControl
{

public ModernCheckboxTree()
{
InitializeComponent();
}



//checkBox单击事件
private void menuSelectChanged(object sender, RoutedEventArgs e)
{
//得到单击的对象
TreeViewItem tree = VisualUpwardSearch<TreeViewItem>(e.OriginalSource as DependencyObject) as TreeViewItem;
TreeModel tree2 = (TreeModel)tree.Header;
if (tree2.IsChecked == true)
{
//如果选中则其父项也应该选中
if (tree2.Parent != null)
{
tree2.Parent.IsChecked = true;

}
if (tree2.Children != null)
{
//如果选中则他的所有子类都要被选中
foreach (TreeModel child in tree2.Children)
{
child.IsChecked = true;
}
}
}
else
{
//如果取消选中子项也应该取消选中
foreach (TreeModel child in tree2.Children)
{
child.IsChecked = false;
}
int i = 0;
//当其父类不为空,可以判断是否和自己同级的IsChecked都为false,如果是父类就也不被选中
if (tree2.Parent != null)
{
foreach (TreeModel child2 in tree2.Parent.Children)
{
if (child2.IsChecked == false)
i++;
else
break;
}
if (i == tree2.Parent.Children.Count)
{
tree2.Parent.IsChecked = false;
}
}
}
}


/// <summary>
/// 控件数据
/// </summary>
private IList<Model.TreeModel> _itemsSourceData;
public IList<Model.TreeModel> ItemsSourceData
{
get { return _itemsSourceData; }
set
{
_itemsSourceData = value;
tvZsmTree.ItemsSource = _itemsSourceData;
}
}




/// <summary>
/// 设置对应Id的项为选中状态
/// </summary>
/// <param name="id"></param>
/// <param name="treeList"></param>
/// <returns></returns>
public int SetCheckedById(string id, IList<Model.TreeModel> treeList)
{
foreach (var tree in treeList)
{
if (tree.Id.Equals(id))
{
tree.IsChecked = true;
return 1;
}
if (SetCheckedById(id, tree.Children) == 1)
{
return 1;
}
}

return 0;
}
/// <summary>
/// 设置对应Id的项为选中状态
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public int SetCheckedById(string id)
{
foreach (var tree in ItemsSourceData)
{
if (tree.Id.Equals(id))
{
tree.IsChecked = true;
return 1;
}
if (SetCheckedById(id, tree.Children) == 1)
{
return 1;
}
}

return 0;
}

/// <summary>
/// 获取选中项
/// </summary>
/// <returns></returns>
public IList<Model.TreeModel> CheckedItemsIgnoreRelation()
{

return GetCheckedItemsIgnoreRelation(_itemsSourceData);
}
/// <summary>
/// 私有方法,忽略层次关系的情况下,获取选中项
/// </summary>
/// <param name="list"></param>
/// <returns></returns>
private IList<Model.TreeModel> GetCheckedItemsIgnoreRelation(IList<Model.TreeModel> list)
{
IList<Model.TreeModel> treeList = new List<Model.TreeModel>();
foreach (var tree in list)
{
if (tree.IsChecked)
{
treeList.Add(tree);
}
foreach (var child in GetCheckedItemsIgnoreRelation(tree.Children))
{
treeList.Add(child);
}
}
return treeList;
}



#region 选中某项单击右键
/// <summary>
/// 选中某项所有子项菜单事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void menuSelectAllChild_Click(object sender, RoutedEventArgs e)
{
if (tvZsmTree.SelectedItem != null)
{
Model.TreeModel tree = (Model.TreeModel)tvZsmTree.SelectedItem;
tree.IsChecked = true;
SetChildrenChecked(true,tree);
}
}
/// <summary>
/// 设置所有子项的选中状态
/// </summary>
/// <param name="isChecked"></param>
/// <param name="tree"></param>
public void SetChildrenChecked(bool isChecked,TreeModel tree)
{
foreach (TreeModel child in tree.Children)
{
child.IsChecked = isChecked;
SetChildrenChecked(isChecked,child);
}
}
#endregion






#region 右键菜单事件

/// <summary>
/// 设置所有子项展开状态
/// </summary>
/// <param name="isExpanded"></param>
/// <param name="tree"></param>
public void SetChildrenExpanded(bool isExpanded, TreeModel tree)
{
foreach (TreeModel child in tree.Children)
{
child.IsExpanded = isExpanded;
SetChildrenExpanded(isExpanded, child);
}
}


/// <summary>
/// 全部展开菜单事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void menuExpandAll_Click(object sender, RoutedEventArgs e)
{
foreach (Model.TreeModel tree in tvZsmTree.ItemsSource)
{
tree.IsExpanded = true;
SetChildrenExpanded(true,tree);
}
}

/// <summary>
/// 全部折叠菜单事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void menuUnExpandAll_Click(object sender, RoutedEventArgs e)
{
foreach (Model.TreeModel tree in tvZsmTree.ItemsSource)
{
tree.IsExpanded = false;
SetChildrenExpanded(false, tree);
}
}

/// <summary>
/// 全部选中事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void menuSelectAll_Click(object sender, RoutedEventArgs e)
{
foreach (Model.TreeModel tree in tvZsmTree.ItemsSource)
{
tree.IsChecked = true;
SetChildrenExpanded(true, tree);
}
}

/// <summary>
/// 全部取消选中
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void menuUnSelectAll_Click(object sender, RoutedEventArgs e)
{
foreach (Model.TreeModel tree in tvZsmTree.ItemsSource)
{
tree.IsChecked = false;
SetChildrenChecked(false,tree);
}
}
#endregion



/// <summary>
/// 鼠标右键事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TreeViewItem_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
TreeViewItem item = VisualUpwardSearch<TreeViewItem>(e.OriginalSource as DependencyObject) as TreeViewItem;
if (item != null)
{
item.Focus();
e.Handled = true;
}
}






static DependencyObject VisualUpwardSearch<T>(DependencyObject source)
{
while (source != null && source.GetType() != typeof(T))
source = VisualTreeHelper.GetParent(source);

return source;
}
}
}


(3)TreeModel.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;



//***************************************************
//
// 文件名(FileName) : TreeModel.cs
//
// 作者(Author) : gl
//
// 创建时间(CreateAt): 2014-12-30 14:23:58
//
// 描述(Description) : 供TreeView实用的数据模型
//
//***************************************************


namespace FirstFloor.ModernUI.Model
{
public class TreeModel : INotifyPropertyChanged
{
#region 私有变量
/// <summary>
/// Id值
/// </summary>
private string _id;
/// <summary>
/// 显示的名称
/// </summary>
private string _name;
/// <summary>
/// 图标路径
/// </summary>
private string _icon;
/// <summary>
/// 选中状态
/// </summary>
private bool _isChecked;
/// <summary>
/// 折叠状态
/// </summary>
private bool _isExpanded;
/// <summary>
/// 子项
/// </summary>
private IList<TreeModel> _children;
/// <summary>
/// 父项
/// </summary>
private TreeModel _parent;
#endregion

/// <summary>
/// 构造
/// </summary>
public TreeModel()
{
Children = new List<TreeModel>();
_isChecked = false;
IsExpanded = false;
_icon = "/Images/16_16/folder_go.png";
}

/// <summary>
/// 键值
/// </summary>
public string Id
{
get { return _id; }
set { _id = value; }
}

/// <summary>
/// 显示的字符
/// </summary>
public string Name
{
get { return _name; }
set { _name = value; }
}

/// <summary>
/// 图标
/// </summary>
public string Icon
{
get { return _icon; }
set { _icon = value; }
}

/// <summary>
/// 指针悬停时的显示说明
/// </summary>
public string ToolTip
{
get
{
return String.Format("{0}-{1}", Id, Name);
}
}

/// <summary>
/// 是否选中
/// </summary>
public bool IsChecked
{
get
{
return _isChecked;
}
set
{
_isChecked = value;
NotifyPropertyChanged("IsChecked");
}
}

/// <summary>
/// 是否展开
/// </summary>
public bool IsExpanded
{
get { return _isExpanded; }
set
{
//折叠状态改变
_isExpanded = value;
NotifyPropertyChanged("IsExpanded");
}
}

/// <summary>
/// 父项
/// </summary>
public TreeModel Parent
{
get { return _parent; }
set { _parent = value; }
}

/// <summary>
/// 子项
/// </summary>
public IList<TreeModel> Children
{
get { return _children; }
set { _children = value; }
}





/// <summary>
/// 属性改变事件
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
}



(4)引用

 <my:ModernCheckboxTree  x:Name="ztvTest"  />