protected virtual void OnBeginDrag(ChessmanPreviewDragEventArgs e) { var parent = Parent as Checkerboard; var canvas = parent.Canvas; parent.Children.Remove(this); Width = parent.CellSize; Height = parent.CellSize; canvas.Children.Add(this); }
public Chessman() { bool isMove = false; bool leftClick = false; bool enabled = false; bool captureMouse = false; Point start = new Point(); Checkerboard parent = null; Canvas canvas = null; MouseLeftButtonDown += (sender, e) => { if (!(captureMouse = Freedom)) { return; } parent = VisualTreeHelper.GetParent(this) as Checkerboard; if (parent == null) { return; } canvas = parent.Canvas; if (canvas == null) { return; } PreviewMouseDown += HookMouseLeftButton; PreviewMouseUp += HookMouseLeftButton; if (captureMouse) { CaptureMouse(); } start = e.GetPosition(canvas); enabled = true; leftClick = true; e.Handled = true; }; MouseMove += (sender, e) => { if (!enabled) { return; } var curr = e.GetPosition(canvas); if (Freedom && (isMove || Math.Abs(curr.X - start.X) > 4 || Math.Abs(curr.Y - start.Y) > 4)) { var oldColumn = (int)GetValue(Checkerboard.ColumnProperty); var oldRow = (int)GetValue(Checkerboard.RowProperty); ChessmanPreviewDragEventArgs eventArgs; if (!isMove) { // begin drag isMove = true; eventArgs = new ChessmanPreviewDragEventArgs(BeginDragEvent, this, parent, oldColumn, oldRow) { StartPointRelativeToCanvas = start, PointRelativeToCanvas = curr }; RaiseEvent(eventArgs); if (eventArgs.Cancel) { enabled = false; return; } OnBeginDrag(eventArgs); } // drag eventArgs = new ChessmanPreviewDragEventArgs(DragEvent, this, parent, oldColumn, oldRow) { StartPointRelativeToCanvas = start, PointRelativeToCanvas = curr }; RaiseEvent(eventArgs); OnDrag(eventArgs); e.Handled = true; } }; MouseLeftButtonUp += (sender, e) => { if (!enabled) { return; } enabled = false; if (isMove) { // end drag isMove = false; bool hitSuccess = false; ChessmanDragEventArgs eventArgs = null; var oldColumn = (int)GetValue(Checkerboard.ColumnProperty); var oldRow = (int)GetValue(Checkerboard.RowProperty); VisualTreeHelper.HitTest(canvas, d => d is Checkerboard ? HitTestFilterBehavior.ContinueSkipChildren : HitTestFilterBehavior.ContinueSkipSelf, r => { if (r.VisualHit is Checkerboard checkerboard) { var curr = e.GetPosition(checkerboard); var columns = checkerboard.Columns; var rows = checkerboard.Rows; var cellSize = checkerboard.CellSize; var newColumn = (int)(curr.X / cellSize); var newRow = (int)(curr.Y / cellSize); if (newColumn >= 0 && newColumn < columns && newRow >= 0 && newRow < rows) { eventArgs = new ChessmanDragEventArgs(PreviewEndDragEvent, this, parent, oldColumn, oldRow, checkerboard, newColumn, newRow); RaiseEvent(eventArgs); if (!eventArgs.Cancel) { hitSuccess = true; eventArgs = new ChessmanDragEventArgs(EndDragEvent, this, parent, oldColumn, oldRow, eventArgs.NewCheckerboard, eventArgs.NewColumn, eventArgs.NewRow); OnEndDrag(eventArgs); RaiseEvent(eventArgs); } else { System.Diagnostics.Debug.Print("cancel"); } } } return(HitTestResultBehavior.Stop); }, new PointHitTestParameters(e.GetPosition(canvas))); if (!hitSuccess) { if (eventArgs != null) { eventArgs = new ChessmanDragEventArgs(CancelDragEvent, this, parent, oldColumn, oldRow, eventArgs.NewCheckerboard, eventArgs.NewColumn, eventArgs.NewRow); } else { eventArgs = new ChessmanDragEventArgs(CancelDragEvent, this, parent, oldColumn, oldRow, null, 0, 0); } OnCancelDrag(eventArgs); RaiseEvent(eventArgs); } } else { if (leftClick) { // click leftClick = false; RaiseEvent(new RoutedEventArgs(LeftClickEvent, this)); } } if (captureMouse) { ReleaseMouseCapture(); } PreviewMouseDown -= HookMouseLeftButton; PreviewMouseUp -= HookMouseLeftButton; e.Handled = true; }; bool rightClick = false; MouseRightButtonDown += delegate { rightClick = true; }; MouseLeave += delegate { rightClick = false; leftClick = false; }; MouseRightButtonUp += delegate { if (rightClick) { rightClick = false; RaiseEvent(new RoutedEventArgs(RightClickEvent, this)); } }; Loaded += delegate { if (VisualTreeHelper.GetParent(this) is Checkerboard checkerboard) { CellSize = checkerboard.CellSize; } }; }
protected virtual void OnDrag(ChessmanPreviewDragEventArgs e) { Canvas.SetLeft(this, e.PointRelativeToCanvas.X - Width / 2); Canvas.SetTop(this, e.PointRelativeToCanvas.Y - Height / 2); }