mirror of
https://gitee.com/akwkevin/aistudio.-wpf.-diagram
synced 2026-03-05 01:00:50 +08:00
支持添加中间节点
This commit is contained in:
@@ -46,7 +46,8 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
this.ColorViewModel.RightArrowPathStyle = ArrowPathStyle.None;
|
||||
}
|
||||
ColorViewModel.PropertyChanged += ColorViewModel_PropertyChanged;
|
||||
ColorViewModel.PropertyChanged += ConnectorViewModel_PropertyChanged;
|
||||
this.PropertyChanged += ConnectorViewModel_PropertyChanged;
|
||||
|
||||
var routetype = GlobalType.AllTypes.Where(p => typeof(IRouter).IsAssignableFrom(p)).FirstOrDefault(p => p.Name == RouterMode);
|
||||
Router = routetype != null ? (System.Activator.CreateInstance(routetype) as IRouter) : new RouterNormal();
|
||||
@@ -57,18 +58,12 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
this.SourceConnectorInfo = sourceConnectorInfo;
|
||||
this.SinkConnectorInfo = sinkConnectorInfo;
|
||||
DeleteConnectionCommand = new SimpleCommand(DeleteConnection);
|
||||
AddVertexCommand = new SimpleCommand(AddVertex);
|
||||
AddVertexCommand = new SimpleCommand(AddVertex);
|
||||
}
|
||||
|
||||
private void ColorViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
private void ConnectorViewModel_PropertyChanged1(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == nameof(ColorViewModel.LeftArrowPathStyle) ||
|
||||
e.PropertyName == nameof(ColorViewModel.LeftArrowSizeStyle) ||
|
||||
e.PropertyName == nameof(ColorViewModel.RightArrowPathStyle) ||
|
||||
e.PropertyName == nameof(ColorViewModel.RightArrowSizeStyle))
|
||||
{
|
||||
UpdatePathGeneratorResult();
|
||||
}
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override SelectableDesignerItemBase ToXmlObject()
|
||||
@@ -90,6 +85,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
return typeof(ConnectionItem);
|
||||
}
|
||||
|
||||
#region 属性
|
||||
private PointBase _sourceA;
|
||||
public PointBase SourceA
|
||||
{
|
||||
@@ -99,10 +95,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
}
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _sourceA, value))
|
||||
{
|
||||
UpdateArea();
|
||||
}
|
||||
SetProperty(ref _sourceA, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,37 +108,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
}
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _sourceB, value))
|
||||
{
|
||||
UpdateArea();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ObservableCollection<ConnectorPoint> _connectionPoints = new ObservableCollection<ConnectorPoint>();
|
||||
public ObservableCollection<ConnectorPoint> ConnectionPoints
|
||||
{
|
||||
get
|
||||
{
|
||||
return _connectionPoints;
|
||||
}
|
||||
private set
|
||||
{
|
||||
if (_connectionPoints != null)
|
||||
{
|
||||
foreach (var connectionPoint in _connectionPoints)
|
||||
{
|
||||
connectionPoint.PropertyChanged -= new WeakINPCEventHandler(ConnectionPoint_PropertyChanged).Handler;
|
||||
}
|
||||
}
|
||||
SetProperty(ref _connectionPoints, value);
|
||||
if (_connectionPoints != null)
|
||||
{
|
||||
foreach (var connectionPoint in _connectionPoints)
|
||||
{
|
||||
connectionPoint.PropertyChanged += new WeakINPCEventHandler(ConnectionPoint_PropertyChanged).Handler;
|
||||
}
|
||||
}
|
||||
SetProperty(ref _sourceB, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,12 +173,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
}
|
||||
private set
|
||||
{
|
||||
RectangleBase oldarea = _area;
|
||||
if (SetProperty(ref _area, value))
|
||||
{
|
||||
UpdatePathGeneratorResult();
|
||||
OutTextItemLocation(oldarea, value);
|
||||
}
|
||||
SetProperty(ref _area, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -266,7 +224,19 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
}
|
||||
|
||||
//待完善这两处
|
||||
public List<LinkVertexModel> Vertices { get; } = new List<LinkVertexModel>();
|
||||
private ObservableCollection<LinkVertexModel> _vertices = new ObservableCollection<LinkVertexModel>();
|
||||
public ObservableCollection<LinkVertexModel> Vertices
|
||||
{
|
||||
get
|
||||
{
|
||||
return _vertices;
|
||||
}
|
||||
private set
|
||||
{
|
||||
SetProperty(ref _vertices, value);
|
||||
}
|
||||
}
|
||||
|
||||
public List<LinkLabelModel> Labels { get; set; } = new List<LinkLabelModel>();
|
||||
|
||||
public virtual Dictionary<string, string> PropertiesSetting
|
||||
@@ -289,11 +259,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
}
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _sourceConnectorInfo, value))
|
||||
{
|
||||
SourceA = PointHelper.GetPointForConnector(_sourceConnectorInfo);
|
||||
(_sourceConnectorInfo.DataItem as INotifyPropertyChanged).PropertyChanged += new WeakINPCEventHandler(ConnectorViewModel_PropertyChanged).Handler;
|
||||
}
|
||||
SetProperty(ref _sourceConnectorInfo, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,14 +272,8 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
}
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _sinkConnectorInfo, value))
|
||||
{
|
||||
SourceB = _sinkConnectorInfo.Position;
|
||||
if (_sinkConnectorInfo is FullyCreatedConnectorInfo)
|
||||
{
|
||||
(((FullyCreatedConnectorInfo)_sinkConnectorInfo).DataItem as INotifyPropertyChanged).PropertyChanged += new WeakINPCEventHandler(ConnectorViewModel_PropertyChanged).Handler;
|
||||
}
|
||||
}
|
||||
SetProperty(ref _sinkConnectorInfo, value);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -350,6 +310,95 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
}
|
||||
|
||||
public bool IsPortless => SourceConnectorInfo?.DataItem?.Connectors?.Count() == 0;
|
||||
#endregion
|
||||
|
||||
#region 方法
|
||||
public SimpleCommand DeleteConnectionCommand
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public SimpleCommand AddVertexCommand
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void ConnectorViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (sender is ConnectorViewModel)
|
||||
{
|
||||
switch (e.PropertyName)
|
||||
{
|
||||
case nameof(SourceA):
|
||||
case nameof(SourceB):
|
||||
UpdateArea();
|
||||
break;
|
||||
case nameof(Area):
|
||||
UpdatePathGeneratorResult();
|
||||
if (e is ValuePropertyChangedEventArgs valuePropertyChangedEventArgs)
|
||||
{
|
||||
OutTextItemLocation((RectangleBase)valuePropertyChangedEventArgs.OldValue, (RectangleBase)valuePropertyChangedEventArgs.NewValue);
|
||||
}
|
||||
break;
|
||||
case nameof(Vertices):
|
||||
foreach (var vertice in Vertices)
|
||||
{
|
||||
vertice.PropertyChanged += new WeakINPCEventHandler(ConnectorViewModel_PropertyChanged).Handler;
|
||||
}
|
||||
break;
|
||||
case nameof(SourceConnectorInfo):
|
||||
SourceA = PointHelper.GetPointForConnector(SourceConnectorInfo);
|
||||
(SourceConnectorInfo.DataItem as INotifyPropertyChanged).PropertyChanged += new WeakINPCEventHandler(ConnectorViewModel_PropertyChanged).Handler;
|
||||
break;
|
||||
case nameof(SinkConnectorInfo):
|
||||
SourceB = SinkConnectorInfo.Position;
|
||||
if (SinkConnectorInfo is FullyCreatedConnectorInfo)
|
||||
{
|
||||
(((FullyCreatedConnectorInfo)SinkConnectorInfo).DataItem as INotifyPropertyChanged).PropertyChanged += new WeakINPCEventHandler(ConnectorViewModel_PropertyChanged).Handler;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
else if (sender is ColorViewModel)
|
||||
{
|
||||
if (e.PropertyName == nameof(ColorViewModel.LeftArrowPathStyle) ||
|
||||
e.PropertyName == nameof(ColorViewModel.LeftArrowSizeStyle) ||
|
||||
e.PropertyName == nameof(ColorViewModel.RightArrowPathStyle) ||
|
||||
e.PropertyName == nameof(ColorViewModel.RightArrowSizeStyle))
|
||||
{
|
||||
UpdatePathGeneratorResult();
|
||||
}
|
||||
}
|
||||
else if (sender is DesignerItemViewModelBase)
|
||||
{
|
||||
switch (e.PropertyName)
|
||||
{
|
||||
case nameof(DesignerItemViewModelBase.ItemHeight):
|
||||
case nameof(DesignerItemViewModelBase.ItemWidth):
|
||||
case nameof(DesignerItemViewModelBase.Left):
|
||||
case nameof(DesignerItemViewModelBase.Top):
|
||||
SourceA = PointHelper.GetPointForConnector(this.SourceConnectorInfo);
|
||||
if (IsFullConnection)
|
||||
{
|
||||
SourceB = PointHelper.GetPointForConnector(this.SinkConnectorInfoFully);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (sender is LinkVertexModel)
|
||||
{
|
||||
switch (e.PropertyName)
|
||||
{
|
||||
case nameof(ConnectorPoint.Left):
|
||||
case nameof(ConnectorPoint.Top):
|
||||
UpdatePathGeneratorResult();
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateArea()
|
||||
{
|
||||
@@ -405,18 +454,19 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
case ConnectorOrientation.Left:
|
||||
{
|
||||
EndPoint = new PointBase(PathGeneratorResult.TargetMarkerPosition.X, PathGeneratorResult.TargetMarkerPosition.Y - ColorViewModel.RightArrowSize / 2);
|
||||
break; }
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ConnectorOrientation.Top:
|
||||
{
|
||||
EndPoint = new PointBase(PathGeneratorResult.TargetMarkerPosition.X - ColorViewModel.RightArrowSize / 2, PathGeneratorResult.TargetMarkerPosition.Y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
case ConnectorOrientation.Right:
|
||||
{
|
||||
EndPoint = new PointBase(PathGeneratorResult.TargetMarkerPosition.X - ColorViewModel.RightArrowSize, PathGeneratorResult.TargetMarkerPosition.Y - ColorViewModel.RightArrowSize / 2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
case ConnectorOrientation.Bottom:
|
||||
{
|
||||
EndPoint = new PointBase(PathGeneratorResult.TargetMarkerPosition.X - ColorViewModel.RightArrowSize / 2, PathGeneratorResult.TargetMarkerPosition.Y - ColorViewModel.RightArrowSize);
|
||||
@@ -433,48 +483,6 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
EndAngle = PathGeneratorResult.TargetMarkerAngle;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void ConnectorViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
switch (e.PropertyName)
|
||||
{
|
||||
case "ItemHeight":
|
||||
case "ItemWidth":
|
||||
case "Left":
|
||||
case "Top":
|
||||
SourceA = PointHelper.GetPointForConnector(this.SourceConnectorInfo);
|
||||
if (IsFullConnection)
|
||||
{
|
||||
SourceB = PointHelper.GetPointForConnector(this.SinkConnectorInfoFully);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void ConnectionPoint_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
switch (e.PropertyName)
|
||||
{
|
||||
case "Left":
|
||||
case "Top":
|
||||
RaisePropertyChanged(nameof(ConnectionPoints));
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public SimpleCommand DeleteConnectionCommand
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public SimpleCommand AddVertexCommand
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
private void DeleteConnection(object args)
|
||||
{
|
||||
if (this.Parent is IDiagramViewModel)
|
||||
@@ -489,7 +497,10 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
MouseButtonEventArgs mosueArg = ((EventToCommandArgs)parameter).EventArgs as MouseButtonEventArgs;
|
||||
var position = mosueArg.GetPosition(((EventToCommandArgs)parameter).Sender as IInputElement);
|
||||
|
||||
ConnectionPoints.Add(new ConnectorPoint(position.X, position.Y));
|
||||
var vertice = new LinkVertexModel(this, new PointBase(position.X, position.Y));
|
||||
vertice.PropertyChanged += new WeakINPCEventHandler(ConnectorViewModel_PropertyChanged).Handler;
|
||||
Vertices.Add(vertice);
|
||||
UpdatePathGeneratorResult();
|
||||
|
||||
if (!((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control))
|
||||
{
|
||||
@@ -497,58 +508,6 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ExecuteEditCommand(object param)
|
||||
{
|
||||
if (this.OutTextItem != null) return;
|
||||
AddText("");
|
||||
}
|
||||
|
||||
public void AddText(string text)
|
||||
{
|
||||
if (this.Parent is IDiagramViewModel)
|
||||
{
|
||||
var diagramVM = this.Parent as IDiagramViewModel;
|
||||
|
||||
TextDesignerItemViewModel textitem = new TextDesignerItemViewModel();
|
||||
textitem.ItemWidth = Double.NaN;
|
||||
textitem.ItemHeight = double.NaN;
|
||||
//if (this.PathMode == DrawMode.ConnectingLineBoundary.ToString())
|
||||
//{
|
||||
// var mid = (int)(ConnectionPoints.Count / 2);
|
||||
// var p = PathGenerators.SegmentMiddlePoint(ConnectionPoints[mid - 1], ConnectionPoints[mid]);
|
||||
// textitem.Left = this.Area.Left + p.X + 2;
|
||||
// textitem.Top = this.Area.Top + p.Y - 15;
|
||||
//}
|
||||
//else
|
||||
{
|
||||
textitem.Left = this.Area.Left + this.Area.Width / 2 - 16;
|
||||
textitem.Top = this.Area.Top + this.Area.Height / 2 - 5;
|
||||
}
|
||||
textitem.Watermark = null;
|
||||
textitem.ZIndex = diagramVM.Items.Count;
|
||||
textitem.ParentId = this.Id;
|
||||
textitem.ParentItem = this;
|
||||
textitem.ColorViewModel.FillColor = new ColorObject() { Color = Colors.White };
|
||||
textitem.Text = text;
|
||||
|
||||
diagramVM.DirectAddItemCommand.Execute(textitem);
|
||||
|
||||
this.OutTextItem = textitem;
|
||||
}
|
||||
}
|
||||
|
||||
public void OutTextItemLocation(RectangleBase oldArea, RectangleBase newArea)
|
||||
{
|
||||
if (this.OutTextItem is TextDesignerItemViewModel text)
|
||||
{
|
||||
var oldpoint = new PointBase(oldArea.Left + oldArea.Width / 2, oldArea.Top + oldArea.Height / 2);
|
||||
var newpoint = new PointBase(newArea.Left + newArea.Width / 2, newArea.Top + newArea.Height / 2);
|
||||
|
||||
text.Left = text.Left + newpoint.X - oldpoint.X;
|
||||
text.Top = text.Top + newpoint.Y - oldpoint.Y;
|
||||
}
|
||||
}
|
||||
|
||||
private (PointBase? source, PointBase? target) FindConnectionPoints(PointBase[] route)
|
||||
{
|
||||
if (IsPortless) // Portless
|
||||
@@ -624,7 +583,58 @@ namespace AIStudio.Wpf.DiagramDesigner
|
||||
return minPoint;
|
||||
}
|
||||
|
||||
#region 双击添加
|
||||
protected override void ExecuteEditCommand(object param)
|
||||
{
|
||||
if (this.OutTextItem != null) return;
|
||||
AddText("");
|
||||
}
|
||||
|
||||
public void AddText(string text)
|
||||
{
|
||||
if (this.Parent is IDiagramViewModel)
|
||||
{
|
||||
var diagramVM = this.Parent as IDiagramViewModel;
|
||||
|
||||
TextDesignerItemViewModel textitem = new TextDesignerItemViewModel();
|
||||
textitem.ItemWidth = Double.NaN;
|
||||
textitem.ItemHeight = double.NaN;
|
||||
//if (this.PathMode == DrawMode.ConnectingLineBoundary.ToString())
|
||||
//{
|
||||
// var mid = (int)(ConnectionPoints.Count / 2);
|
||||
// var p = PathGenerators.SegmentMiddlePoint(ConnectionPoints[mid - 1], ConnectionPoints[mid]);
|
||||
// textitem.Left = this.Area.Left + p.X + 2;
|
||||
// textitem.Top = this.Area.Top + p.Y - 15;
|
||||
//}
|
||||
//else
|
||||
{
|
||||
textitem.Left = this.Area.Left + this.Area.Width / 2 - 16;
|
||||
textitem.Top = this.Area.Top + this.Area.Height / 2 - 5;
|
||||
}
|
||||
textitem.Watermark = null;
|
||||
textitem.ZIndex = diagramVM.Items.Count;
|
||||
textitem.ParentId = this.Id;
|
||||
textitem.ParentItem = this;
|
||||
textitem.ColorViewModel.FillColor = new ColorObject() { Color = Colors.White };
|
||||
textitem.Text = text;
|
||||
|
||||
diagramVM.DirectAddItemCommand.Execute(textitem);
|
||||
|
||||
this.OutTextItem = textitem;
|
||||
}
|
||||
}
|
||||
|
||||
public void OutTextItemLocation(RectangleBase oldArea, RectangleBase newArea)
|
||||
{
|
||||
if (this.OutTextItem is TextDesignerItemViewModel text)
|
||||
{
|
||||
var oldpoint = new PointBase(oldArea.Left + oldArea.Width / 2, oldArea.Top + oldArea.Height / 2);
|
||||
var newpoint = new PointBase(newArea.Left + newArea.Width / 2, newArea.Top + newArea.Height / 2);
|
||||
|
||||
text.Left = text.Left + newpoint.X - oldpoint.X;
|
||||
text.Top = text.Top + newpoint.Y - oldpoint.Y;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user