using System; using System.Windows.Controls.Primitives; using System.Windows.Documents; using System.Windows.Media; using System.Windows; using System.Windows.Shapes; using Brushes = System.Windows.Media.Brushes; using Size = System.Windows.Size; using EGC = ExtendedGrid.Microsoft.Windows.Controls; using System.Diagnostics; namespace MECF.Framework.UI.Client.DataGridTransform.DataGrid.Microsoft.Windows.Controls.Primitives { public class DataGridCellDragToFillAdorner : Adorner { public event EventHandler OnDragStart; public event EventHandler OnDragCompleted; public event EventHandler OnDragDelta; private readonly Brush _defaultBrush; private readonly VisualCollection _adornerVisuals; private readonly Thumb _thumb2; private readonly Rectangle _rec; private readonly Rectangle _recShadow; private Rect _lastBoundRect; #region Constructors public DataGridCellDragToFillAdorner(UIElement adornedElement, Size originCellSize) : base(adornedElement) { _lastBoundRect = new Rect(0, 0, originCellSize.Width, originCellSize.Height); _adornerVisuals = new VisualCollection(this); _defaultBrush = Brushes.ForestGreen; _thumb2 = new Thumb(); _rec = new Rectangle() { StrokeThickness = 2 }; _recShadow = new Rectangle() { StrokeThickness = 2, StrokeDashArray = { 1, 1 }, Opacity = 0.5, Visibility = Visibility.Hidden }; _thumb2.DragStarted += Thumb2OnDragStarted; _thumb2.DragDelta += Thumb2_DragDelta; _thumb2.DragCompleted += Thumb2OnDragCompleted; _adornerVisuals.Add(_rec); _adornerVisuals.Add(_recShadow); _adornerVisuals.Add(_thumb2); } protected override void OnInitialized(EventArgs e) { base.OnInitialized(e); LoadDefaultThumbStyle(); LoadDefaultBorderStyle(); } #endregion #region Properties protected override int VisualChildrenCount => _adornerVisuals.Count; internal int StartCellIndex { get; private set; } internal int EndCellIndex { get; private set; } #endregion #region Dps public static readonly DependencyProperty ThumbStyleProperty = DependencyProperty.Register( nameof(ThumbStyle), typeof(Style), typeof(DataGridCellDragToFillAdorner), new PropertyMetadata(default(Style), ThumbStyleChangedCallback)); private static void ThumbStyleChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is DataGridCellDragToFillAdorner adr && e.NewValue is Style s) adr.SetThumbStyle(s); } public Style ThumbStyle { get => (Style)GetValue(ThumbStyleProperty); set => SetValue(ThumbStyleProperty, value); } public static readonly DependencyProperty BorderColorProperty = DependencyProperty.Register( nameof(BorderColorBrush), typeof(Brush), typeof(DataGridCellDragToFillAdorner), new PropertyMetadata(default(Brush), BorderColorPropertyChangedCallback)); private static void BorderColorPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is DataGridCellDragToFillAdorner adr && e.NewValue is Brush b) { adr.SetBorderBrush(b); } } public Brush BorderColorBrush { get => (Brush)GetValue(BorderColorProperty); set => SetValue(BorderColorProperty, value); } #endregion #region Methods protected override Visual GetVisualChild(int index) { return _adornerVisuals[index]; } protected override Size ArrangeOverride(Size finalSize) { /*_rec.Arrange(_lastBoundRect); _thumb2.Arrange(new Rect(_lastBoundRect.Width - 5, _lastBoundRect.Height + _lastBoundRect.Y - 5, 10, 10));*/ _rec.Arrange(new Rect(0, 0, finalSize.Width, finalSize.Height)); //_recShadow.Arrange(new Rect(0, 0, finalSize.Width, finalSize.Height)); _thumb2.Arrange(new Rect(finalSize.Width - 5, finalSize.Height - 5, 10, 10)); return base.ArrangeOverride(finalSize); } private void SetThumbStyle(Style style) { if (style != null && style.TargetType == typeof(Thumb)) _thumb2.Style = style; else { // Load default style LoadDefaultThumbStyle(); } } private void SetBorderBrush(Brush brush) { if (brush != null) { _rec.Stroke = brush; _recShadow.Stroke = brush; } else { LoadDefaultBorderStyle(); } } private void LoadDefaultThumbStyle() { var brush = _defaultBrush; if (BorderColorBrush != null) brush = BorderColorBrush; _thumb2.Width = 10; _thumb2.Height = 10; _thumb2.Background = brush; _thumb2.BorderThickness = new Thickness(0); } private void LoadDefaultBorderStyle() { var brush = _defaultBrush; if (BorderColorBrush != null) brush = BorderColorBrush; _rec.Stroke = brush; _recShadow.Stroke = brush; } /// /// 绘制选择范围的虚线框。 /// /// /// /// internal void ArrangeSelectionBound(Rect boundRect, int startCellIndex, int endCellIndex) { _lastBoundRect.X = boundRect.X; _lastBoundRect.Y = boundRect.Y; _lastBoundRect.Width = boundRect.Width; _lastBoundRect.Height = boundRect.Height; _recShadow.Arrange(_lastBoundRect); StartCellIndex = startCellIndex; EndCellIndex = endCellIndex; //Debug.WriteLine($"Adorner Bound: {_lastBoundRect}", "Adorner"); } /// /// 获取拖动选择的范围。 /// /// internal Rect GetSelectionBound() { return _lastBoundRect; } /// /// 取消填充操作。 /// internal void Cancel() { if (_thumb2.IsDragging) _thumb2.CancelDrag(); } #endregion #region Event Handlers private void Thumb2OnDragStarted(object sender, DragStartedEventArgs e) { _recShadow.Visibility = Visibility.Visible; OnDragStart?.Invoke(this, e); } private void Thumb2OnDragCompleted(object sender, DragCompletedEventArgs e) { _recShadow.Visibility = Visibility.Hidden; if (!e.Canceled) { _rec.Arrange(_lastBoundRect); _recShadow.Arrange(_lastBoundRect); _thumb2.Arrange(new Rect(_lastBoundRect.Width - 5, _lastBoundRect.Height + _lastBoundRect.Y - 5, 10, 10)); OnDragCompleted?.Invoke(this, e); } } private void Thumb2_DragDelta(object sender, DragDeltaEventArgs e) { OnDragDelta?.Invoke(this, e); } #endregion } }