diff --git a/WorkBench/MainWindow.xaml b/WorkBench/MainWindow.xaml
index 4257bd4..c15f300 100644
--- a/WorkBench/MainWindow.xaml
+++ b/WorkBench/MainWindow.xaml
@@ -74,16 +74,17 @@
+ x:Name="FlowChartScrollViewer">
+
+ Background="#F2EEE8"
+ AllowDrop="True"
+ MouseDown="FlowChartCanvas_MouseDown"
+ MouseMove="FlowChartCanvas_MouseMove"
+ MouseUp="FlowChartCanvas_MouseUp"
+ MouseWheel="FlowChartCanvas_MouseWheel"
+ Drop="FlowChartCanvas_Drop"
+ DragOver="FlowChartCanvas_DragOver"/>
diff --git a/WorkBench/MainWindow.xaml.cs b/WorkBench/MainWindow.xaml.cs
index 14e24d2..27b4bfd 100644
--- a/WorkBench/MainWindow.xaml.cs
+++ b/WorkBench/MainWindow.xaml.cs
@@ -8,20 +8,18 @@ using Serein.WorkBench.Node.View;
using Serein.WorkBench.Themes;
using Serein.WorkBench.tool;
using System.Collections.Concurrent;
-using System.Configuration;
using System.Diagnostics;
-using System.Drawing.Drawing2D;
using System.IO;
using System.Reflection;
-using System.Threading.Tasks.Dataflow;
+using System.Security.Cryptography.Xml;
using System.Windows;
using System.Windows.Controls;
-using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
+using System.Windows.Media.Media3D;
using System.Windows.Shapes;
-using static Serein.WorkBench.MainWindow;
+using DataObject = System.Windows.DataObject;
namespace Serein.WorkBench
{
@@ -202,7 +200,9 @@ namespace Serein.WorkBench
/// 标记是否正在拖动控件
///
private bool IsDragging;
-
+ private bool IsCanvasDragging;
+ private Point startMousePosition;
+ private TranslateTransform transform;
@@ -217,6 +217,9 @@ namespace Serein.WorkBench
// 重定向 Console 输出
var logTextWriter = new LogTextWriter(WriteLog);
Console.SetOut(logTextWriter);
+
+ transform = new TranslateTransform();
+ FlowChartCanvas.RenderTransform = transform;
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
@@ -397,7 +400,7 @@ namespace Serein.WorkBench
{
fromNode.Node.UpstreamBranch.Add(toNode.Node);
}
- var connection = new Connection { Start = fromNode, End = toNode, Type = connectionType };
+ var connection = new Connection { Start = fromNode, End = toNode, Type = connectionType };
toNode.Node.PreviousNodes.Add(fromNode.Node);
BsControl.Draw(FlowChartCanvas, connection);
ConfigureLineContextMenu(connection);
@@ -1268,10 +1271,119 @@ namespace Serein.WorkBench
};
FlowChartCanvas.Children.Add(currentLine);
- FlowChartCanvas.MouseMove += FlowChartCanvas_MouseMove;
+ //FlowChartCanvas.MouseMove += FlowChartCanvas_MouseMove;
this.KeyDown += MainWindow_KeyDown;
}
+
+ #region 拖动画布实现缩放平移效果
+ private void FlowChartCanvas_MouseDown(object sender, MouseButtonEventArgs e)
+ {
+ if (e.MiddleButton == MouseButtonState.Pressed)
+ {
+ IsCanvasDragging = true;
+ startMousePosition = e.GetPosition(this);
+ FlowChartCanvas.CaptureMouse();
+ }
+ }
+
+ private void FlowChartCanvas_MouseUp(object sender, MouseButtonEventArgs e)
+ {
+ if (IsCanvasDragging)
+ {
+ IsCanvasDragging = false;
+ FlowChartCanvas.ReleaseMouseCapture();
+
+ foreach(var line in connections)
+ {
+ line.Refresh();
+ }
+ }
+ }
+
+ private void FlowChartCanvas_MouseWheel(object sender, MouseWheelEventArgs e)
+ {
+ if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
+ {
+ double scale = e.Delta > 0 ? 1.1 : 0.9;
+
+ foreach (UIElement element in FlowChartCanvas.Children)
+ {
+ element.RenderTransformOrigin = new Point(0.5, 0.5);
+ var transform = element.RenderTransform as ScaleTransform;
+ if (transform == null)
+ {
+ transform = new ScaleTransform();
+ element.RenderTransform = transform;
+ }
+ transform.ScaleX *= scale;
+ transform.ScaleY *= scale;
+ }
+
+ foreach (var line in connections)
+ {
+ line.Refresh();
+ }
+ }
+ }
+ private void AdjustCanvasSizeAndContent(double deltaX, double deltaY)
+ {
+ var myCanvas = FlowChartCanvas;
+
+
+ // 获取画布的边界框
+ Rect transformedBounds = myCanvas.RenderTransform.TransformBounds(new Rect(myCanvas.RenderSize));
+
+ // 检查画布的左边缘是否超出视图
+ if (transformedBounds.Left > 0)
+ {
+ double offsetX = transformedBounds.Left;
+ myCanvas.Width += offsetX;
+ transform.X -= offsetX;
+
+ // 移动所有控件的位置
+ foreach (UIElement child in myCanvas.Children)
+ {
+ Canvas.SetLeft(child, Canvas.GetLeft(child) + offsetX);
+ }
+ }
+
+ // 检查画布的上边缘是否超出视图
+ if (transformedBounds.Top > 0)
+ {
+ double offsetY = transformedBounds.Top;
+ myCanvas.Height += offsetY;
+ transform.Y -= offsetY;
+
+ // 移动所有控件的位置
+ foreach (UIElement child in myCanvas.Children)
+ {
+ Canvas.SetTop(child, Canvas.GetTop(child) + offsetY);
+ }
+ }
+
+ //Debug.Print($" {FlowChartScrollViewer.ActualWidth} / {FlowChartScrollViewer.ActualHeight} -- {transformedBounds.Right} / {transformedBounds.Bottom}");
+
+ var size = 50;
+ // 检查画布的右边缘是否超出当前宽度
+ if (transformedBounds.Right + size < FlowChartScrollViewer.ActualWidth)
+ {
+
+ double extraWidth = FlowChartScrollViewer.ActualWidth - transformedBounds.Right;
+ FlowChartCanvas.Width += extraWidth;
+ }
+
+ // 检查画布的下边缘是否超出当前高度
+ if (transformedBounds.Bottom + size < FlowChartScrollViewer.ActualHeight)
+ {
+ double extraHeight = FlowChartScrollViewer.ActualHeight - transformedBounds.Bottom;
+ FlowChartCanvas.Height += extraHeight;
+ }
+
+ }
+
+ #endregion
+
///
/// FlowChartCanvas中移动时处理,用于实时更新连接线的终点位置。
///
@@ -1289,6 +1401,22 @@ namespace Serein.WorkBench
currentLine.X2 = position.X;
currentLine.Y2 = position.Y;
}
+
+ if (IsCanvasDragging)
+ {
+ Point currentMousePosition = e.GetPosition(this);
+ double deltaX = currentMousePosition.X - startMousePosition.X;
+ double deltaY = currentMousePosition.Y - startMousePosition.Y;
+
+ transform.X += deltaX;
+ transform.Y += deltaY;
+
+
+ startMousePosition = currentMousePosition;
+
+ // 调整画布大小和控件位置
+ AdjustCanvasSizeAndContent(deltaX, deltaY);
+ }
}
///
@@ -1395,7 +1523,7 @@ namespace Serein.WorkBench
{
IsConnecting = false;
startConnectBlock = null;
- FlowChartCanvas.MouseMove -= FlowChartCanvas_MouseMove;
+ //FlowChartCanvas.MouseMove -= FlowChartCanvas_MouseMove;
// 移除虚线
if (currentLine != null)
@@ -2006,6 +2134,7 @@ namespace Serein.WorkBench
{
public static Connection Draw(Canvas canvas, Connection connection)
{
+ connection.Canvas = canvas;
UpdateBezierLine(canvas, connection);
//MakeDraggable(canvas, connection, connection.Start);
//MakeDraggable(canvas, connection, connection.End);
@@ -2105,6 +2234,8 @@ namespace Serein.WorkBench
public class Connection
{
public ConnectionType Type { get; set; }
+ public Canvas Canvas { get; set; }// 贝塞尔曲线所在画布
+
public System.Windows.Shapes.Path BezierPath { get; set; }// 贝塞尔曲线路径
public System.Windows.Shapes.Path ArrowPath { get; set; } // 箭头路径
@@ -2119,9 +2250,14 @@ namespace Serein.WorkBench
canvas.Children.Remove(ArrowPath); // 移除线
_animationStoryboard?.Stop(); // 停止动画
}
+
+ public void Refresh()
+ {
+ BsControl.Draw(Canvas,this);
+ }
}
- public class BezierLineDrawer
+ public static class BezierLineDrawer
{
public enum Localhost
{
@@ -2280,6 +2416,8 @@ namespace Serein.WorkBench
}
#endregion
+
+
}
}
\ No newline at end of file