protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); Point cursorPosition = e.GetPosition(this); switch (this.visualState) { case Visuals.VisualState.Idle: { VisualGraphics visualHit = this.DrawHandleWhenMouseOverVisual <VisualPolyline>(cursorPosition); // 处理鼠标状态 this.ProcessSelectedVisualCursor(visualHit, cursorPosition); break; } case Visuals.VisualState.Translate: { double x = cursorPosition.X - this.previousPosition.X; double y = cursorPosition.Y - this.previousPosition.Y; this.translateVisual.Translate(x, y); foreach (GraphicsPolyline polyline in this.associatedPolylines) { List <Point> pointList = null; if (this.translateVisual.ID == polyline.AssociatedGraphics1) { // 移动的图形是第一个图形 Point firstConnector = this.translateVisual.GetConnectorPoint(polyline.Graphics1Handle); ConnectionLocations firstConnectorLocation = this.translateVisual.GetConnectorLocation(polyline.Graphics1Handle); Point secondConnector = polyline.PointList.LastOrDefault(); if (string.IsNullOrEmpty(polyline.AssociatedGraphics2)) { // 连接点的另一端不在图形上 pointList = GraphicsUtility.MakeConnectionPath(firstConnector, firstConnectorLocation, secondConnector); } else { // 连接点的另一端在图形上 VisualGraphics secondVisual = this.VisualList.FirstOrDefault(v => v.ID == polyline.AssociatedGraphics2); ConnectionLocations secondConnectorLocation = secondVisual.Graphics.GetConnectorLocation(polyline.Graphics2Handle); pointList = GraphicsUtility.MakeConnectionPath(firstConnector, firstConnectorLocation, secondConnector, secondConnectorLocation); } } else if (this.translateVisual.ID == polyline.AssociatedGraphics2) { // 移动的图形是第二个图形 Point secondConnector = this.translateVisual.GetConnectorPoint(polyline.Graphics2Handle); ConnectionLocations secondConnectorLocation = this.translateVisual.GetConnectorLocation(polyline.Graphics2Handle); Point firstConnector = polyline.PointList.FirstOrDefault(); if (string.IsNullOrEmpty(polyline.AssociatedGraphics1)) { // 连接点的另一端不在图形上 // 规定必须在图形上,不允许只有第二个点在图形上,而第一个点不在。但是允许第一个点在图形上,第二个点不在 pointList = GraphicsUtility.MakeConnectionPath(secondConnector, secondConnectorLocation, firstConnector); pointList.Reverse(); } else { // 连接点的另一端在图形上 VisualGraphics firstVisual = this.VisualList.FirstOrDefault(v => v.ID == polyline.AssociatedGraphics1); ConnectionLocations firstConnectorLocation = firstVisual.Graphics.GetConnectorLocation(polyline.Graphics1Handle); pointList = GraphicsUtility.MakeConnectionPath(firstConnector, firstConnectorLocation, secondConnector, secondConnectorLocation); } } else { throw new NotImplementedException(); } VisualPolyline visualPolyline = this.VisualList.OfType <VisualPolyline>().FirstOrDefault(v => v.ID == polyline.ID); visualPolyline.Update(pointList); } this.previousPosition = cursorPosition; break; } case Visuals.VisualState.Connecting: { GraphicsPolyline graphicsPolyline = this.polyline.Graphics as GraphicsPolyline; Point secondConnector = cursorPosition; // 检测鼠标是否在某个图形上面 VisualGraphics visualHit = this.DrawHandleWhenMouseOverVisual <VisualPolyline>(cursorPosition); if (visualHit == null || visualHit == this.firstVisual) { this.secondVisual = null; graphicsPolyline.AssociatedGraphics2 = null; // 更新连接线 List <Point> points = GraphicsUtility.MakeConnectionPath(this.firstConnector, this.firstConnectorLocation, secondConnector); this.polyline.Update(points); } else { // 如果当前鼠标下的元素和选中的是不同一个元素,那么就表示有连接的元素了 // 运行到此处说明两个图形被连接起来了 this.secondVisual = visualHit; // 运行到这里说明折线的另一端已经在图形的连接点范围内了 int handle; Point handlePoint; ConnectionLocations secondConnectorLocation; if (this.secondVisual.Graphics.GetNearestConnectorHandle(cursorPosition, out handle, out handlePoint, out secondConnectorLocation)) { secondConnector = handlePoint; graphicsPolyline.AssociatedGraphics2 = this.secondVisual.ID; graphicsPolyline.Graphics2Handle = handle; // 更新连接线 List <Point> points = GraphicsUtility.MakeConnectionPath(this.firstConnector, this.firstConnectorLocation, secondConnector, secondConnectorLocation); this.polyline.Update(points); } else { // 鼠标已经在第二个图形上了,但是没有放在连接点附近 List <Point> points = GraphicsUtility.MakeConnectionPath(this.firstConnector, this.firstConnectorLocation, secondConnector); this.polyline.Update(points); } } break; } case Visuals.VisualState.Resizing: { this.selectedVisual.Resize(this.resizeLocation, this.resizeCenter, cursorPosition); break; } case Visuals.VisualState.InputState: { break; } default: throw new NotImplementedException(); } }
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) { base.OnMouseLeftButtonDown(e); this.previouseSelectedVisual = this.selectedVisual; Point cursorPosition = e.GetPosition(this); VisualGraphics visualHit = this.HitTestFirstVisual <ExcludedNullVisual>(cursorPosition); if (visualHit == null) { if (this.selectedVisual != null) { this.selectedVisual.IsSelected = false; this.selectedVisual.IsDrawHandle = false; this.selectedVisual.Render(); this.selectedVisual = null; } // 停止编辑状态 this.StopVisualInputState(this.previouseSelectedVisual); TextBoxEditor.Visibility = Visibility.Collapsed; // 重置到空闲状态 this.visualState = Visuals.VisualState.Idle; return; } this.ProcessSelectedVisualChanged(this.selectedVisual, visualHit); this.selectedVisual = visualHit; this.previousPosition = cursorPosition; if (e.ClickCount == 2) { // 双击图形,那么进入编辑状态 this.visualState = Visuals.VisualState.InputState; this.StartVisualInputState(this.selectedVisual); } else { this.StopVisualInputState(this.previouseSelectedVisual); #region 判断是否点击了连接点 for (int i = 0; i < visualHit.ConnectionHandles; i++) { Rect bounds = visualHit.GetConnectorBounds(i); if (bounds.Contains(cursorPosition)) { Point center = bounds.GetCenter(); ConnectionLocations location = visualHit.GetConnectorLocation(i); this.visualState = Visuals.VisualState.Connecting; GraphicsPolyline graphics = new GraphicsPolyline() { AssociatedGraphics1 = visualHit.ID, Graphics1Handle = i }; this.polyline = this.DrawVisual(graphics) as VisualPolyline; this.firstConnector = center; this.firstConnectorLocation = location; this.firstVisual = visualHit; return; } } #endregion #region 判断是否点击了Reisze点 for (int i = 0; i < visualHit.ResizeHandles; i++) { Rect bounds = visualHit.GetResizeHandleBounds(i); if (bounds.Contains(cursorPosition)) { this.resizeCenter = bounds.GetCenter(); this.resizeLocation = visualHit.Graphics.GetResizeLocation(this.resizeCenter); this.visualState = Visuals.VisualState.Resizing; return; } } #endregion #region 是平移状态 // 获取当前被移动的图形所有的连接点信息 this.associatedPolylines = this.GetAssociatedPolylines(visualHit.Graphics); Console.WriteLine("关联的折线有{0}个", this.associatedPolylines.Count); this.translateVisual = visualHit; this.visualState = Visuals.VisualState.Translate; #endregion } }