添加项目文件。
This commit is contained in:
69
Wpf.Ui.Extend/UserControls/MultiCheckTreeView.xaml
Normal file
69
Wpf.Ui.Extend/UserControls/MultiCheckTreeView.xaml
Normal file
@@ -0,0 +1,69 @@
|
||||
<UserControl
|
||||
x:Class="Wpf.Ui.Extend.UserControls.MultiCheckTreeView"
|
||||
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:models="clr-namespace:Wpf.Ui.Extend.Models"
|
||||
d:DesignHeight="300"
|
||||
d:DesignWidth="300"
|
||||
mc:Ignorable="d">
|
||||
<Grid>
|
||||
<DockPanel>
|
||||
<Border>
|
||||
<TreeView x:Name="MultiCheckTree" d:ItemsSource="{d:SampleData}">
|
||||
<TreeView.ContextMenu>
|
||||
<ContextMenu />
|
||||
</TreeView.ContextMenu>
|
||||
<TreeView.ItemContainerStyle>
|
||||
<Style TargetType="{x:Type TreeViewItem}">
|
||||
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
|
||||
<EventSetter Event="UIElement.PreviewMouseRightButtonDown" Handler="TreeViewItem_PreviewMouseRightButtonDown" />
|
||||
</Style>
|
||||
</TreeView.ItemContainerStyle>
|
||||
<TreeView.ItemTemplate>
|
||||
<HierarchicalDataTemplate DataType="{x:Type models:TreeModel}" ItemsSource="{Binding Children}">
|
||||
<StackPanel
|
||||
x:Name="staTree"
|
||||
Margin="-2,0,0,0"
|
||||
Orientation="Horizontal">
|
||||
<CheckBox
|
||||
Click="treeNode_Click"
|
||||
FontFamily="微软雅黑"
|
||||
FontSize="14"
|
||||
IsChecked="{Binding IsChecked, Mode=TwoWay}"
|
||||
Tag="{Binding Children}"
|
||||
ToolTip="{Binding ToolTip}">
|
||||
<!--<CheckBox.ContextMenu>
|
||||
<ContextMenu>
|
||||
<MenuItem
|
||||
x:Name="menuSelectAllChild"
|
||||
Click="menuSelectAllChild_Click"
|
||||
Header="全部选中子项">
|
||||
<MenuItem.Icon>
|
||||
<Image Source="/FamilyTools;component/Images/16_16/Checked_16px.png" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
</ContextMenu>
|
||||
</CheckBox.ContextMenu>-->
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image VerticalAlignment="Center" Source="{Binding Icon}" />
|
||||
<TextBlock
|
||||
VerticalAlignment="Center"
|
||||
Foreground="Black"
|
||||
Text="{Binding Name}" />
|
||||
</StackPanel>
|
||||
</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>
|
||||
242
Wpf.Ui.Extend/UserControls/MultiCheckTreeView.xaml.cs
Normal file
242
Wpf.Ui.Extend/UserControls/MultiCheckTreeView.xaml.cs
Normal file
@@ -0,0 +1,242 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
|
||||
using Wpf.Ui.Extend.Models;
|
||||
|
||||
namespace Wpf.Ui.Extend.UserControls
|
||||
{
|
||||
public partial class MultiCheckTreeView : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造
|
||||
/// </summary>
|
||||
public MultiCheckTreeView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 控件数据
|
||||
/// </summary>
|
||||
private IList<TreeModel> itemsSourceData;
|
||||
|
||||
/// <summary>
|
||||
/// 控件数据
|
||||
/// </summary>
|
||||
public IList<TreeModel> ItemsSourceData
|
||||
{
|
||||
get => itemsSourceData;
|
||||
set
|
||||
{
|
||||
itemsSourceData = value;
|
||||
MultiCheckTree.ItemsSource = itemsSourceData;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取选中所有项(父节点和子节点)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IList<TreeModel> CheckedItemsIgnoreRelation()
|
||||
{
|
||||
return GetCheckedItemsIgnoreRelation(itemsSourceData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置对应Id的项为选中状态
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public int SetCheckedById(string id, IList<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>
|
||||
/// <param name="list"></param>
|
||||
/// <returns></returns>
|
||||
private IList<TreeModel> GetCheckedItemsIgnoreRelation(IList<TreeModel> list)
|
||||
{
|
||||
IList<TreeModel> treeList = [];
|
||||
foreach (var tree in list)
|
||||
{
|
||||
if (tree.IsChecked == true)
|
||||
{
|
||||
treeList.Add(tree);
|
||||
}
|
||||
|
||||
//第二次调用方法时由于没有子节点即为空,所以不进行执行下面语句,跳出下面的foreach语句
|
||||
foreach (var child in GetCheckedItemsIgnoreRelation(tree.Children))
|
||||
{
|
||||
treeList.Add(child);
|
||||
}
|
||||
}
|
||||
|
||||
return treeList;
|
||||
}
|
||||
|
||||
private static DependencyObject VisualUpwardSearch<T>(DependencyObject source)
|
||||
{
|
||||
while (source != null && source.GetType() != typeof(T))
|
||||
source = VisualTreeHelper.GetParent(source);
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 全部展开菜单事件
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void menuExpandAll_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (MultiCheckTree.ItemsSource != null)
|
||||
{
|
||||
foreach (TreeModel tree in MultiCheckTree.ItemsSource)
|
||||
{
|
||||
tree.IsExpanded = true;
|
||||
tree.SetChildrenExpanded(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 全部选中事件
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void menuSelectAll_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (MultiCheckTree.ItemsSource != null)
|
||||
{
|
||||
foreach (TreeModel tree in MultiCheckTree.ItemsSource)
|
||||
{
|
||||
tree.IsChecked = true;
|
||||
tree.SetChildrenChecked(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 选中所有子项菜单事件
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void menuSelectAllChild_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (MultiCheckTree.SelectedItem != null)
|
||||
{
|
||||
var tree = (TreeModel)MultiCheckTree.SelectedItem;
|
||||
tree.IsChecked = true;
|
||||
tree.SetChildrenChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 全部折叠菜单事件
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void menuUnExpandAll_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (MultiCheckTree.ItemsSource != null)
|
||||
{
|
||||
foreach (TreeModel tree in MultiCheckTree.ItemsSource)
|
||||
{
|
||||
tree.IsExpanded = false;
|
||||
tree.SetChildrenExpanded(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 全部取消选中
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void menuUnSelectAll_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (MultiCheckTree.ItemsSource != null)
|
||||
{
|
||||
foreach (TreeModel tree in MultiCheckTree.ItemsSource)
|
||||
{
|
||||
tree.IsChecked = false;
|
||||
tree.SetChildrenChecked(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void treeNode_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (VisualUpwardSearch<TreeViewItem>(e.OriginalSource as DependencyObject) is TreeViewItem item)
|
||||
{
|
||||
item.Focus();
|
||||
if (MultiCheckTree.SelectedItem != null)
|
||||
{
|
||||
var tree = (TreeModel)MultiCheckTree.SelectedItem;
|
||||
tree.SetChildrenChecked();
|
||||
tree.SetParentChecked();
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 鼠标右键事件
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void TreeViewItem_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (VisualUpwardSearch<TreeViewItem>(e.OriginalSource as DependencyObject) is TreeViewItem item)
|
||||
{
|
||||
item.Focus();
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
82
Wpf.Ui.Extend/UserControls/MultiSelectorHelper.cs
Normal file
82
Wpf.Ui.Extend/UserControls/MultiSelectorHelper.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
|
||||
namespace Wpf.Ui.Extend.UserControls
|
||||
{
|
||||
/// <summary>
|
||||
/// 多选控件绑定选中项
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <c><DataGrid</c>
|
||||
/// <c>local:MultiSelectorHelper.BindableSelectedItems="{Binding SelectItems, Mode=OneWayToSource}"</c>
|
||||
/// <c>local:MultiSelectorHelper.MonitorSelectionChanged="True" /></c>
|
||||
/// </example>
|
||||
public class MultiSelectorHelper : DependencyObject
|
||||
{
|
||||
public static readonly DependencyProperty BindableSelectedItemsProperty = DependencyProperty.Register(
|
||||
"BindableSelectedItems",
|
||||
typeof(IList),
|
||||
typeof(MultiSelectorHelper),
|
||||
new PropertyMetadata(default(IList))
|
||||
);
|
||||
|
||||
public static IList GetBindableSelectedItems(DependencyObject obj)
|
||||
{
|
||||
return (IList)obj.GetValue(BindableSelectedItemsProperty);
|
||||
}
|
||||
|
||||
public static void SetBindableSelectedItems(DependencyObject obj, IList value)
|
||||
{
|
||||
obj.SetValue(BindableSelectedItemsProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty MonitorSelectionChangedProperty = DependencyProperty.RegisterAttached(
|
||||
"SetMonitorSelectionChanged",
|
||||
typeof(bool),
|
||||
typeof(MultiSelectorHelper),
|
||||
new PropertyMetadata(false, MonitorSelectionChangedPropertyChangedCallBack)
|
||||
);
|
||||
|
||||
private static void MonitorSelectionChangedPropertyChangedCallBack(
|
||||
DependencyObject d,
|
||||
DependencyPropertyChangedEventArgs e
|
||||
)
|
||||
{
|
||||
if (d is not MultiSelector selector)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
if ((bool)e.NewValue)
|
||||
{
|
||||
selector.SelectionChanged += Selector_SelectionChanged;
|
||||
}
|
||||
else
|
||||
{
|
||||
selector.SelectionChanged -= Selector_SelectionChanged;
|
||||
}
|
||||
}
|
||||
|
||||
private static void Selector_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (sender is MultiSelector selector)
|
||||
{
|
||||
SetBindableSelectedItems(selector, selector.SelectedItems);
|
||||
selector.GetBindingExpression(BindableSelectedItemsProperty).UpdateSource();
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetMonitorSelectionChanged(DependencyObject element, bool value)
|
||||
{
|
||||
element.SetValue(MonitorSelectionChangedProperty, value);
|
||||
}
|
||||
|
||||
public static bool GetMonitorSelectionChanged(DependencyObject element)
|
||||
{
|
||||
return (bool)element.GetValue(MonitorSelectionChangedProperty);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user