WPF DataGrid开箱即用支持全部勾选的DataGridCheckBoxColumn
本文由 飞羽流星(Flithor/毛茸茸松鼠先生/Mr.Squirrel.Downy)原创,欢迎分享转载,但禁止以原创二次发布<br>原文地址:<a href="https://www.cnblogs.com/Flithor/p/17877473.html" target="_blank" rel="noopener">https://www.cnblogs.com/Flithor/p/17877473.html</a>以往在WPF的DataGrid上实现实时勾选交互非常麻烦,要用DataGridTemplateColumn写样式还要写一些后端代码,还有绑定和转换器,或者处理事件。但是现在都不需要了,使用开箱即用的DataGridCheckAllColumn,简化你的勾选代码实现!
它支持列表筛选变化反馈,支持虚拟化,支持单项勾选变化的更新反馈。
效果预览:
而且非常简单好用:
<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns><strong>注意!</strong>
如果你在DataGrid上设置了<strong>VirtualizingPanel.IsVirtualizing="True"</strong>应用虚拟化
需要同时设置<strong>VirtualizingPanel.VirtualizationMode="Standard"</strong>,避免出现绑定实例错误的BugDataGridCheckAllColumn类的实现:
// 代码作者: 飞羽流星(Flithor/Mr.Squirrel.Downy/毛茸茸松鼠先生)// 开源许可: MIT// =======警告=======// 使用开源代码的风险自负using System;using System.Collections.Generic;using System.ComponentModel;using System.Globalization;using System.Linq;using System.Reflection;using System.Runtime.Remoting.Messaging;using System.Windows;using System.Windows.Controls;using System.Windows.Controls.Primitives;using System.Windows.Data;using System.Windows.Media;using Expression = System.Linq.Expressions.Expression;namespace Flithor_Codes{ /// /// 一个支持勾选所有的DataGrid列 /// public class DataGridCheckAllColumn : DataGridBoundColumn { #region 私有字段 //列头中的CheckBox private readonly CheckBox checkAllCheckBox; //所属DataGrid控件 private DataGrid ownerDatagrid; //所属DataGrid控件的列表版本,如果版本号改变则说明列表改变 private Func getInnerEnumeratorVersion; //缓存的列表版本号 private int cachedInnerVersion; //CheckBox的默认样式 private static Style _defaultElementStyle; #endregion #region 初始化控件 public static Style DefaultElementStyle { get {<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>if (_defaultElementStyle == null)<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>{<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> var style = new Style(typeof(CheckBox))<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> {<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> Setters =<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> {<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> new Setter(UIElement.FocusableProperty, false),<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> new Setter(CheckBox.HorizontalAlignmentProperty, HorizontalAlignment.Center),<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> new Setter(CheckBox.VerticalAlignmentProperty, VerticalAlignment.Center)<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> }<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> };<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> style.Seal();<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> _defaultElementStyle = style;<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>}<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>return _defaultElementStyle; } } static DataGridCheckAllColumn() { //重写单元格元素默认样式 ElementStyleProperty.OverrideMetadata(typeof(DataGridCheckAllColumn), new FrameworkPropertyMetadata(DefaultElementStyle)); //使列默认只读 IsReadOnlyProperty.OverrideMetadata(typeof(DataGridCheckAllColumn), new FrameworkPropertyMetadata(true)); //不允许重排此列 CanUserReorderProperty.OverrideMetadata(typeof(DataGridCheckAllColumn), new FrameworkPropertyMetadata(false)); //不允许修改此列宽度 CanUserResizeProperty.OverrideMetadata(typeof(DataGridCheckAllColumn), new FrameworkPropertyMetadata(false)); //不允许点击列头排序项目 CanUserSortProperty.OverrideMetadata(typeof(DataGridCheckAllColumn), new FrameworkPropertyMetadata(false)); } public DataGridCheckAllColumn() { //设置列头 Header = checkAllCheckBox = new CheckBox(); } protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) { if (ownerDatagrid != null) return; ownerDatagrid = GetParentDataGrid(); if (ownerDatagrid == null) return; InitInnerVersionDetect(ownerDatagrid.Items); ((INotifyPropertyChanged)ownerDatagrid.Items).PropertyChanged += OnPropertyChanged; //如果DataGrid当前已有项目,则初始化绑定 checkAllCheckBox.IsEnabled = ownerDatagrid.Items.Count > 0; if (checkAllCheckBox.IsEnabled)<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>ResetCheckCurrentAllBinding(); } //寻找所属DataGrid控件(如果还没初始化完毕,可能返回空值) private DataGrid GetParentDataGrid() { DependencyObject elment = checkAllCheckBox; do {<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>elment = VisualTreeHelper.GetParent(elment); } while (elment != null && !(elment is DataGrid)); return elment as DataGrid; } #endregion #region 构建单元格元素(方法的功能不言自明) protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem) { return GenerateCheckBox(false, cell, dataItem); } protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem) { return GenerateCheckBox(true, cell, dataItem); } private CheckBox GenerateCheckBox(bool isEditing, DataGridCell cell, object dataItem) { var checkBox = new CheckBox(); ApplyStyle(isEditing, checkBox); ApplyBinding(dataItem, checkBox); return checkBox; } private void ApplyBinding(object dataItem, CheckBox checkBox) { var binding = CloneBinding(Binding, dataItem); if (binding is Binding newBinding) {<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>newBinding.Mode = BindingMode.TwoWay;<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>newBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; } BindingOperations.ClearBinding(checkBox, CheckBox.IsCheckedProperty); checkBox.SetBinding(CheckBox.IsCheckedProperty, binding); } internal void ApplyStyle(bool isEditing, FrameworkElement element) { Style style = PickStyle(isEditing); if (style != null) {<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>element.Style = style; } } private Style PickStyle(bool isEditing) { Style style = isEditing ? EditingElementStyle : ElementStyle; if (isEditing && (style == null)) {<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>style = ElementStyle; } return style; } #endregion #region 更新绑定 private void OnPropertyChanged(object sender, PropertyChangedEventArgs e) { if (ownerDatagrid == null || e.PropertyName != nameof(ownerDatagrid.Items.Count))<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>return; //如果项目数量发生改变意味着列表更新了 if (ownerDatagrid.Items.Count == 0) {<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>//如果列表空了,那就移除绑定并禁用列头勾选控件<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>BindingOperations.ClearBinding(checkAllCheckBox, CheckBox.IsCheckedProperty);<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>checkAllCheckBox.IsEnabled = false; } else {<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>//否则基于当前列表显示项更新绑定<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>ResetCheckCurrentAllBinding();<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>checkAllCheckBox.IsEnabled = true; } } private void ResetCheckCurrentAllBinding() { //如果列表版本号改变则更新,否则无需更新 if (ownerDatagrid == null || !InnerVersionChanged()) return; var checkAllBinding = new MultiBinding {<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>Converter = AllBoolStatusConverter.Default,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>Mode = BindingMode.TwoWay }; //基于所有列表显示项创建绑定 var currentItems = ownerDatagrid.Items.OfType().ToList(); foreach (var item in currentItems) {<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>checkAllBinding.Bindings.Add(CloneBinding((Binding)Binding, item)); } //清除旧绑定 BindingOperations.ClearBinding(checkAllCheckBox, CheckBox.IsCheckedProperty); checkAllCheckBox.SetBinding(CheckBox.IsCheckedProperty, checkAllBinding); } //创建获取内部列表版本号的委托 private void InitInnerVersionDetect(ItemCollection itemCollection) { //Timestamp属性是内部列表的版本号标识,用于表示列表变更的次数 var collectionTimestampProerty = itemCollection.GetType()<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>.GetProperty("Timestamp", BindingFlags.Instance | BindingFlags.NonPublic); //使用Linq的Expression来构建访问Timestamp属性的委托方法 getInnerEnumeratorVersion = Expression.Lambda(Expression.Property(<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>Expression.Constant(itemCollection),<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>collectionTimestampProerty)).Compile(); } //检查内部列表是否发生了更新 private bool InnerVersionChanged() { var currentInnerVersion = getInnerEnumeratorVersion.Invoke(); if (currentInnerVersion != cachedInnerVersion) {<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>cachedInnerVersion = currentInnerVersion;<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>return true; } return false; } //基于已有绑定对象创建一个副本,使用指定的数据源 private static BindingBase CloneBinding(BindingBase bindingBase, object source) { switch (bindingBase) {<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>case Binding binding:<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> var resultBinding = new Binding<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> {<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> Source = source,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> AsyncState = binding.AsyncState,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> BindingGroupName = binding.BindingGroupName,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> BindsDirectlyToSource = binding.BindsDirectlyToSource,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> Converter = binding.Converter,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> ConverterCulture = binding.ConverterCulture,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> ConverterParameter = binding.ConverterParameter,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> //ElementName = binding.ElementName,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> FallbackValue = binding.FallbackValue,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> IsAsync = binding.IsAsync,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> Mode = binding.Mode,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> NotifyOnSourceUpdated = binding.NotifyOnSourceUpdated,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> NotifyOnTargetUpdated = binding.NotifyOnTargetUpdated,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> NotifyOnValidationError = binding.NotifyOnValidationError,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> Path = binding.Path,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> //RelativeSource = binding.RelativeSource,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> StringFormat = binding.StringFormat,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> TargetNullValue = binding.TargetNullValue,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> UpdateSourceExceptionFilter = binding.UpdateSourceExceptionFilter,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> UpdateSourceTrigger = binding.UpdateSourceTrigger,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> ValidatesOnDataErrors = binding.ValidatesOnDataErrors,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> ValidatesOnExceptions = binding.ValidatesOnExceptions,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> XPath = binding.XPath,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> };<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> foreach (var validationRule in binding.ValidationRules)<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> {<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> resultBinding.ValidationRules.Add(validationRule);<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> }<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> return resultBinding;<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>case MultiBinding multiBinding:<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> var resultMultiBinding = new MultiBinding<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> {<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> BindingGroupName = multiBinding.BindingGroupName,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> Converter = multiBinding.Converter,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> ConverterCulture = multiBinding.ConverterCulture,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> ConverterParameter = multiBinding.ConverterParameter,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> FallbackValue = multiBinding.FallbackValue,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> Mode = multiBinding.Mode,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> NotifyOnSourceUpdated = multiBinding.NotifyOnSourceUpdated,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> NotifyOnTargetUpdated = multiBinding.NotifyOnTargetUpdated,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> NotifyOnValidationError = multiBinding.NotifyOnValidationError,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> StringFormat = multiBinding.StringFormat,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> TargetNullValue = multiBinding.TargetNullValue,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> UpdateSourceExceptionFilter = multiBinding.UpdateSourceExceptionFilter,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> UpdateSourceTrigger = multiBinding.UpdateSourceTrigger,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> ValidatesOnDataErrors = multiBinding.ValidatesOnDataErrors,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> ValidatesOnExceptions = multiBinding.ValidatesOnDataErrors,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> };<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> foreach (var validationRule in multiBinding.ValidationRules)<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> {<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> resultMultiBinding.ValidationRules.Add(validationRule);<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> }<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> foreach (var childBinding in multiBinding.Bindings)<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> {<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> resultMultiBinding.Bindings.Add(CloneBinding(childBinding, source));<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> }<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> return resultMultiBinding;<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>case PriorityBinding priorityBinding:<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> var resultPriorityBinding = new PriorityBinding<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> {<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> BindingGroupName = priorityBinding.BindingGroupName,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> FallbackValue = priorityBinding.FallbackValue,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> StringFormat = priorityBinding.StringFormat,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> TargetNullValue = priorityBinding.TargetNullValue,<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> };<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> foreach (var childBinding in priorityBinding.Bindings)<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> {<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> resultPriorityBinding.Bindings.Add(CloneBinding(childBinding, source));<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> }<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> return resultPriorityBinding;<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>default:<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> throw new NotSupportedException("Failed to clone binding"); } } /// /// 用于合并所有bool值到一个值的多值转换器 /// private class AllBoolStatusConverter : IMultiValueConverter { public static readonly AllBoolStatusConverter Default = new AllBoolStatusConverter(); public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) {<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>if (values.Length == 0 || values.OfType().Count() != values.Length)<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> return false;<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>// 检查所有项是否和第一项相同<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>var firstStatus = values.First();<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>foreach (var value in values)<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>{<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> //如果有不同就返回null,表示第三态<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> if (!Equals(value, firstStatus))<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> return null;<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>}<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>return firstStatus; } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) {<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>//如果汇总的值发生变化则更新所有项目<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>var res = new object;<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>for (int i = 0; i < res.Length; i++)<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns> res = value;<DataGrid.Columns>
<fc:DataGridCheckAllColumn Binding="{Binding IsChecked}" />
<DataGridTextColumn Binding="{Binding EntityName}" />
</DataGrid.Columns>return res; } } #endregion }}
来源:https://www.cnblogs.com/Flithor/archive/2023/12/05/17877473.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页:
[1]