Files
SzmediTools/MvdLiteSnoop/DataGridMultiEditSyncBehavior.cs
2025-09-16 16:06:41 +08:00

127 lines
4.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace MvdLiteSnoop
{
public static class DataGridMultiEditSyncBehavior
{
public static readonly DependencyProperty EnableMultiEditSyncProperty =
DependencyProperty.RegisterAttached(
"EnableMultiEditSync",
typeof(bool),
typeof(DataGridMultiEditSyncBehavior),
new PropertyMetadata(false, OnEnableMultiEditSyncChanged));
public static void SetEnableMultiEditSync(DependencyObject obj, bool value) =>
obj.SetValue(EnableMultiEditSyncProperty, value);
public static bool GetEnableMultiEditSync(DependencyObject obj) =>
(bool)obj.GetValue(EnableMultiEditSyncProperty);
private static void OnEnableMultiEditSyncChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is DataGrid dg)
{
if ((bool)e.NewValue)
dg.PreparingCellForEdit += Dg_PreparingCellForEdit;
else
dg.PreparingCellForEdit -= Dg_PreparingCellForEdit;
}
}
private static void Dg_PreparingCellForEdit(object sender, DataGridPreparingCellForEditEventArgs e)
{
var dg = (DataGrid)sender;
var column = e.Column;
if (column.IsReadOnly) return;
// 获取属性名
var propName = column.SortMemberPath;
if (string.IsNullOrWhiteSpace(propName))
propName = GetBindingPath(column);
if (string.IsNullOrEmpty(propName)) return;
var editingElement = e.EditingElement;
// 根据不同控件类型绑定即时事件
if (editingElement is TextBox tb)
{
tb.TextChanged -= Handler;
tb.TextChanged += Handler;
}
else if (editingElement is CheckBox cb)
{
cb.Checked -= Handler;
cb.Unchecked -= Handler;
cb.Checked += Handler;
cb.Unchecked += Handler;
}
else if (editingElement is ComboBox combo)
{
combo.SelectionChanged -= Handler;
combo.SelectionChanged += Handler;
}
void Handler(object s, EventArgs args)
{
var rowItem = e.Row.Item;
var prop = rowItem.GetType().GetProperty(propName, BindingFlags.Public | BindingFlags.Instance);
if (prop == null || !prop.CanWrite) return;
var newValue = prop.GetValue(rowItem);
foreach (var sel in dg.SelectedItems)
{
if (ReferenceEquals(sel, rowItem)) continue;
var selProp = sel.GetType().GetProperty(propName, BindingFlags.Public | BindingFlags.Instance);
if (selProp != null && selProp.CanWrite)
{
try
{
if (selProp.PropertyType.IsAssignableFrom(prop.PropertyType))
{
selProp.SetValue(sel, newValue);
}
else
{
var converted = Convert.ChangeType(newValue, selProp.PropertyType);
selProp.SetValue(sel, converted);
}
}
catch
{
// 类型不兼容时忽略
}
}
}
}
}
private static string GetBindingPath(DataGridColumn column)
{
if (column is DataGridBoundColumn boundCol)
{
if (boundCol.Binding is Binding binding)
return binding.Path?.Path;
}
else if (column is DataGridComboBoxColumn comboCol)
{
if (comboCol.SelectedItemBinding is Binding binding)
return binding.Path?.Path;
if (comboCol.SelectedValueBinding is Binding binding2)
return binding2.Path?.Path;
}
return null;
}
}
}