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; } } }