using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Data; using System.Windows.Input; namespace BPA.UIControl { /// /// DataGrid 详细内容展开列 /// public class DataGridDetailToggleButtonColumn : DataGridBoundColumn { /// /// Initializes a new instance of the class. /// static DataGridDetailToggleButtonColumn() { var elementStyle = (Style)Application.Current.FindResource("RubyerDataGridDetailToggleButtonColumn"); DataGridBoundColumn.ElementStyleProperty.OverrideMetadata(typeof(DataGridDetailToggleButtonColumn), new FrameworkPropertyMetadata(elementStyle)); DataGridBoundColumn.EditingElementStyleProperty.OverrideMetadata(typeof(DataGridDetailToggleButtonColumn), new FrameworkPropertyMetadata(elementStyle)); } /// protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem) { return GenerateToggleButton(isEditing: false, cell); } /// protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem) { return GenerateToggleButton(isEditing: true, cell); } /// /// Applies the binding. /// /// The target. /// The property. internal void ApplyBinding(DependencyObject target, DependencyProperty property) { BindingBase binding = Binding; if (binding != null) { BindingOperations.SetBinding(target, property, binding); } else { BindingOperations.ClearBinding(target, property); } } /// /// Applies the style. /// /// If true, is editing. /// If true, default to element style. /// The element. internal void ApplyStyle(bool isEditing, bool defaultToElementStyle, FrameworkElement element) { Style style = PickStyle(isEditing, defaultToElementStyle); if (style != null) { element.Style = style; } } /// /// Picks the style. /// /// If true, is editing. /// If true, default to element style. /// A Style. private Style PickStyle(bool isEditing, bool defaultToElementStyle) { Style style = (isEditing ? EditingElementStyle : ElementStyle); if (isEditing && defaultToElementStyle && style == null) { style = ElementStyle; } return style; } /// /// Generates the toggle button. /// /// If true, is editing. /// The cell. /// A ToggleButton. private ToggleButton GenerateToggleButton(bool isEditing, DataGridCell cell) { ToggleButton toggleButton = (cell != null) ? (cell.Content as ToggleButton) : null; toggleButton ??= new ToggleButton(); toggleButton.IsThreeState = false; ApplyStyle(isEditing, defaultToElementStyle: true, toggleButton); ApplyBinding(toggleButton, ToggleButton.IsCheckedProperty); return toggleButton; } /// protected override object PrepareCellForEdit(FrameworkElement editingElement, RoutedEventArgs editingEventArgs) { if (editingElement is ToggleButton toggleButton) { toggleButton.Focus(); bool? isChecked = toggleButton.IsChecked; if (IsMouseLeftButtonDown(editingEventArgs)) { toggleButton.IsChecked = !isChecked.GetValueOrDefault(); var dataGridCell = editingElement.GetVisualAncestry().OfType().FirstOrDefault(); dataGridCell.IsEditing = false; } return isChecked; } return false; } /// /// Are the mouse left button down. /// /// The e. /// A bool. private static bool IsMouseLeftButtonDown(RoutedEventArgs e) { if (e is MouseButtonEventArgs mouseButtonEventArgs && mouseButtonEventArgs.ChangedButton == MouseButton.Left) { return mouseButtonEventArgs.ButtonState == MouseButtonState.Pressed; } return false; } } }