private void NCellMouseMove(object sender, NCellMouseEventArgs args) { if (args.MouseEventArgs.LeftButton == MouseButtonState.Pressed && _mouseDownNCell != null) { var currentNCell = GetNCellFromMousePosition(args.MouseEventArgs.GetPosition(this)); if (currentNCell != null && !currentNCell.Equals(_mouseDownNCell) && !currentNCell.Equals(_lastMouseOverNCell)) { var mouseDownNCellRow = (int)_mouseDownNCell.GetValue(Grid.RowProperty); var mouseDownNCellColumn = (int)_mouseDownNCell.GetValue(Grid.ColumnProperty); var currentNCellRow = (int)currentNCell.GetValue(Grid.RowProperty); var currentNCellColumn = (int)currentNCell.GetValue(Grid.ColumnProperty); //计算绘制选中效果的矩形区域的起始点 Point startPoint, endPoint; if (currentNCellRow >= mouseDownNCellRow) { if (currentNCellColumn >= mouseDownNCellColumn) { startPoint = _mouseDownNCell.TranslatePoint(new Point(), NCellContainer); endPoint = currentNCell.TranslatePoint(new Point(currentNCell.ActualWidth, currentNCell.ActualHeight), NCellContainer); } else { startPoint = _mouseDownNCell.TranslatePoint(new Point(_mouseDownNCell.ActualWidth, 0), NCellContainer); endPoint = currentNCell.TranslatePoint(new Point(0, currentNCell.ActualHeight), NCellContainer); } } else { if (currentNCellColumn >= mouseDownNCellColumn) { startPoint = _mouseDownNCell.TranslatePoint(new Point(0, _mouseDownNCell.ActualHeight), NCellContainer); endPoint = currentNCell.TranslatePoint(new Point(currentNCell.ActualWidth, 0), NCellContainer); } else { startPoint = _mouseDownNCell.TranslatePoint(new Point(_mouseDownNCell.ActualWidth, _mouseDownNCell.ActualHeight), NCellContainer); endPoint = currentNCell.TranslatePoint(new Point(0, 0), NCellContainer); } } //设置选中效果 var leftMargin = Math.Min(startPoint.X, endPoint.X); var topMargin = Math.Min(startPoint.Y, endPoint.Y); _effectBorder = new Border() { BorderThickness = new Thickness(2), BorderBrush = Brushes.Blue }; _effectBorder.SetValue(Canvas.LeftProperty, leftMargin); _effectBorder.SetValue(Canvas.TopProperty, topMargin); _effectBorder.Width = Math.Abs(startPoint.X - endPoint.X); _effectBorder.Height = Math.Abs(startPoint.Y - endPoint.Y); _effectBorder.Background = Brushes.SkyBlue; _effectBorder.Opacity = 0.3; //当合并项处于选中边界时 var selectedRect = NTableUtils.BuildRect(startPoint, endPoint); //标识经过合并项的处理,选中区域是否已改变,若已改变则重新扫描,是否有合并项处于边界 bool isSelectionRectChanged; do { isSelectionRectChanged = false; foreach (var mergeItem in _nTableData.MergeCollection) { var mergeItemRect = NTableUtils.TranslateBounds(mergeItem.RootNCell, NCellContainer); if (NTableUtils.IsRectIntersect(selectedRect, mergeItemRect)) { if (mergeItemRect.Y < selectedRect.Y) { _effectBorder.SetValue(Canvas.TopProperty, mergeItemRect.Y); _effectBorder.Height += selectedRect.Y - mergeItemRect.Y; } if (mergeItemRect.X < selectedRect.X) { _effectBorder.SetValue(Canvas.LeftProperty, mergeItemRect.X); _effectBorder.Width += selectedRect.X - mergeItemRect.X; } if (mergeItemRect.Right > selectedRect.Right) { _effectBorder.Width += mergeItemRect.Right - selectedRect.Right; } if (mergeItemRect.Bottom > selectedRect.Bottom) { _effectBorder.Height += mergeItemRect.Bottom - selectedRect.Bottom; } var newSelectionRect = new Rect((double)_effectBorder.GetValue(Canvas.LeftProperty), (double)_effectBorder.GetValue(Canvas.TopProperty), _effectBorder.Width, _effectBorder.Height); if (newSelectionRect != selectedRect) { selectedRect = newSelectionRect; isSelectionRectChanged = true; } } } } while (isSelectionRectChanged); //实时更新选中的单元格集合 _selectedNCells.Clear(); var rows = _nTableData.Rows.Count; var columns = _nTableData.Columns.Count; for (var i = 0; i < rows; i++) { for (var j = 0; j < columns; j++) { if (NTableUtils.IsRectIntersect(NTableUtils.TranslateBounds((FrameworkElement)NCellContainer.Children[i * columns + j], NCellContainer), selectedRect)) { _selectedNCells.Add((NCell)NCellContainer.Children[i * columns + j]); } } } for (var i = 0; i < _selectedNCells.Count; i++) { if (_selectedNCells[i].MergeId != Guid.Empty) { var mergeItem = _nTableData.MergeCollection.First(x => x.Id == _selectedNCells[i].MergeId); mergeItem.ToList().ForEach(x => { if (!_selectedNCells.Contains(x)) { _selectedNCells.Add(x); } }); } } ClearSelection(); EffectContainer.Children.Add(_effectBorder); } _lastMouseOverNCell = currentNCell; } }
private void NCellMouseLeftDown(object sender, NCellMouseEventArgs args) { _mouseDownNCell = GetNCellFromMousePosition(args.MouseEventArgs.GetPosition(this)); ClearSelection(); }