mirror of
https://gitee.com/akwkevin/aistudio.-wpf.-diagram
synced 2026-05-03 22:41:30 +08:00
支持添加中间节点
This commit is contained in:
@@ -33,19 +33,8 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls
|
|||||||
{
|
{
|
||||||
if (this.DataContext is ConnectorPoint point)
|
if (this.DataContext is ConnectorPoint point)
|
||||||
{
|
{
|
||||||
double minLeft = double.MaxValue;
|
point.X += e.HorizontalChange;
|
||||||
double minTop = double.MaxValue;
|
point.Y += e.VerticalChange;
|
||||||
|
|
||||||
double left = point.X;
|
|
||||||
double top = point.Y;
|
|
||||||
minLeft = double.IsNaN(left) ? 0 : Math.Min(left, minLeft);
|
|
||||||
minTop = double.IsNaN(top) ? 0 : Math.Min(top, minTop);
|
|
||||||
|
|
||||||
double deltaHorizontal = Math.Max(-minLeft, e.HorizontalChange);
|
|
||||||
double deltaVertical = Math.Max(-minTop, e.VerticalChange);
|
|
||||||
|
|
||||||
point.X += deltaHorizontal;
|
|
||||||
point.Y += deltaVertical;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,12 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
double targetAngle = TargetMarkerAdjustement(route, link.ColorViewModel.RightArrowSize);
|
double targetAngle = TargetMarkerAdjustement(route, link.ColorViewModel.RightArrowSize);
|
||||||
|
|
||||||
BezierSpline.GetCurveControlPoints(route, out var firstControlPoints, out var secondControlPoints);
|
BezierSpline.GetCurveControlPoints(route, out var firstControlPoints, out var secondControlPoints);
|
||||||
var paths = new string[firstControlPoints.Length];
|
|
||||||
|
DoShift(route, link);
|
||||||
|
DoShift(firstControlPoints, link);
|
||||||
|
DoShift(secondControlPoints, link);
|
||||||
|
|
||||||
|
var paths = new string[firstControlPoints.Length];
|
||||||
|
|
||||||
for (var i = 0; i < firstControlPoints.Length; i++)
|
for (var i = 0; i < firstControlPoints.Length; i++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
{
|
{
|
||||||
public static PointBase[] Normal(IDiagramViewModel _, ConnectorViewModel link)
|
public static PointBase[] Normal(IDiagramViewModel _, ConnectorViewModel link)
|
||||||
{
|
{
|
||||||
return link.Vertices.Select(v => (PointBase)v).ToArray();
|
return link.Vertices.Select(v => v.MiddlePosition).ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -542,7 +542,7 @@
|
|||||||
<MouseBinding MouseAction="LeftDoubleClick" Command="{Binding EditCommand}" CommandParameter="{Binding }" />
|
<MouseBinding MouseAction="LeftDoubleClick" Command="{Binding EditCommand}" CommandParameter="{Binding }" />
|
||||||
</Canvas.InputBindings>
|
</Canvas.InputBindings>
|
||||||
<!--<Polyline x:Name="poly"
|
<!--<Polyline x:Name="poly"
|
||||||
Points="{Binding Path=ConnectionPoints, Converter={x:Static s:ConnectionPointConverter.Instance}}"
|
Points="{Binding Path=Vertices, Converter={x:Static s:ConnectionPointConverter.Instance}}"
|
||||||
Stroke="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}"
|
Stroke="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}"
|
||||||
StrokeThickness="{Binding ColorViewModel.LineWidth}"
|
StrokeThickness="{Binding ColorViewModel.LineWidth}"
|
||||||
StrokeDashArray="{Binding ColorViewModel.LineDashStyle,Converter={StaticResource LineDashConverter}}" />-->
|
StrokeDashArray="{Binding ColorViewModel.LineDashStyle,Converter={StaticResource LineDashConverter}}" />-->
|
||||||
@@ -600,7 +600,7 @@
|
|||||||
</c:DragThumb.InputBindings>
|
</c:DragThumb.InputBindings>
|
||||||
</c:DragThumb>
|
</c:DragThumb>
|
||||||
|
|
||||||
<s:PointContainer x:Name="PART_PointContainer" Style="{StaticResource innerConnectorContainer}" ItemsSource="{Binding ConnectionPoints}" Visibility="Collapsed">
|
<s:PointContainer x:Name="PART_PointContainer" Style="{StaticResource innerConnectorContainer}" ItemsSource="{Binding Vertices}" Visibility="Collapsed">
|
||||||
<s:PointContainer.ItemTemplate>
|
<s:PointContainer.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<Grid>
|
<Grid>
|
||||||
@@ -616,6 +616,7 @@
|
|||||||
</Style>
|
</Style>
|
||||||
</s:PointContainer.Resources>
|
</s:PointContainer.Resources>
|
||||||
</s:PointContainer>
|
</s:PointContainer>
|
||||||
|
|
||||||
<Rectangle Fill="#7F243859" Opacity="0.5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Visibility="{Binding ShouldInsertAnchor, Converter={StaticResource BooleanToVisibilityConverter}}">
|
<Rectangle Fill="#7F243859" Opacity="0.5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Visibility="{Binding ShouldInsertAnchor, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||||
<i:Interaction.Behaviors>
|
<i:Interaction.Behaviors>
|
||||||
<s:ControlMouseLeftButtonDownCommandBehavior Command="{Binding AddVertexCommand}" />
|
<s:ControlMouseLeftButtonDownCommandBehavior Command="{Binding AddVertexCommand}" />
|
||||||
|
|||||||
@@ -91,14 +91,14 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public PointBase Position
|
public virtual PointBase Position
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return new PointBase(Left, Top);
|
return new PointBase(Left, Top);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public PointBase MiddlePosition => new PointBase(Left + ConnectorWidth / 2, Top + ConnectorHeight / 2);
|
public virtual PointBase MiddlePosition => new PointBase(Left + ConnectorWidth / 2, Top + ConnectorHeight / 2);
|
||||||
|
|
||||||
private double connectorWidth = 8;
|
private double connectorWidth = 8;
|
||||||
public double ConnectorWidth
|
public double ConnectorWidth
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
{
|
{
|
||||||
this.ColorViewModel.RightArrowPathStyle = ArrowPathStyle.None;
|
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);
|
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();
|
Router = routetype != null ? (System.Activator.CreateInstance(routetype) as IRouter) : new RouterNormal();
|
||||||
@@ -57,18 +58,12 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
this.SourceConnectorInfo = sourceConnectorInfo;
|
this.SourceConnectorInfo = sourceConnectorInfo;
|
||||||
this.SinkConnectorInfo = sinkConnectorInfo;
|
this.SinkConnectorInfo = sinkConnectorInfo;
|
||||||
DeleteConnectionCommand = new SimpleCommand(DeleteConnection);
|
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) ||
|
throw new NotImplementedException();
|
||||||
e.PropertyName == nameof(ColorViewModel.LeftArrowSizeStyle) ||
|
|
||||||
e.PropertyName == nameof(ColorViewModel.RightArrowPathStyle) ||
|
|
||||||
e.PropertyName == nameof(ColorViewModel.RightArrowSizeStyle))
|
|
||||||
{
|
|
||||||
UpdatePathGeneratorResult();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override SelectableDesignerItemBase ToXmlObject()
|
public override SelectableDesignerItemBase ToXmlObject()
|
||||||
@@ -90,6 +85,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
return typeof(ConnectionItem);
|
return typeof(ConnectionItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region 属性
|
||||||
private PointBase _sourceA;
|
private PointBase _sourceA;
|
||||||
public PointBase SourceA
|
public PointBase SourceA
|
||||||
{
|
{
|
||||||
@@ -99,10 +95,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (SetProperty(ref _sourceA, value))
|
SetProperty(ref _sourceA, value);
|
||||||
{
|
|
||||||
UpdateArea();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,37 +108,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (SetProperty(ref _sourceB, value))
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,12 +173,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
}
|
}
|
||||||
private set
|
private set
|
||||||
{
|
{
|
||||||
RectangleBase oldarea = _area;
|
SetProperty(ref _area, value);
|
||||||
if (SetProperty(ref _area, value))
|
|
||||||
{
|
|
||||||
UpdatePathGeneratorResult();
|
|
||||||
OutTextItemLocation(oldarea, 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 List<LinkLabelModel> Labels { get; set; } = new List<LinkLabelModel>();
|
||||||
|
|
||||||
public virtual Dictionary<string, string> PropertiesSetting
|
public virtual Dictionary<string, string> PropertiesSetting
|
||||||
@@ -289,11 +259,7 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (SetProperty(ref _sourceConnectorInfo, value))
|
SetProperty(ref _sourceConnectorInfo, value);
|
||||||
{
|
|
||||||
SourceA = PointHelper.GetPointForConnector(_sourceConnectorInfo);
|
|
||||||
(_sourceConnectorInfo.DataItem as INotifyPropertyChanged).PropertyChanged += new WeakINPCEventHandler(ConnectorViewModel_PropertyChanged).Handler;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,14 +272,8 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (SetProperty(ref _sinkConnectorInfo, value))
|
SetProperty(ref _sinkConnectorInfo, value);
|
||||||
{
|
|
||||||
SourceB = _sinkConnectorInfo.Position;
|
|
||||||
if (_sinkConnectorInfo is FullyCreatedConnectorInfo)
|
|
||||||
{
|
|
||||||
(((FullyCreatedConnectorInfo)_sinkConnectorInfo).DataItem as INotifyPropertyChanged).PropertyChanged += new WeakINPCEventHandler(ConnectorViewModel_PropertyChanged).Handler;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -350,6 +310,95 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
}
|
}
|
||||||
|
|
||||||
public bool IsPortless => SourceConnectorInfo?.DataItem?.Connectors?.Count() == 0;
|
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()
|
private void UpdateArea()
|
||||||
{
|
{
|
||||||
@@ -405,18 +454,19 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
case ConnectorOrientation.Left:
|
case ConnectorOrientation.Left:
|
||||||
{
|
{
|
||||||
EndPoint = new PointBase(PathGeneratorResult.TargetMarkerPosition.X, PathGeneratorResult.TargetMarkerPosition.Y - ColorViewModel.RightArrowSize / 2);
|
EndPoint = new PointBase(PathGeneratorResult.TargetMarkerPosition.X, PathGeneratorResult.TargetMarkerPosition.Y - ColorViewModel.RightArrowSize / 2);
|
||||||
break; }
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ConnectorOrientation.Top:
|
case ConnectorOrientation.Top:
|
||||||
{
|
{
|
||||||
EndPoint = new PointBase(PathGeneratorResult.TargetMarkerPosition.X - ColorViewModel.RightArrowSize / 2, PathGeneratorResult.TargetMarkerPosition.Y);
|
EndPoint = new PointBase(PathGeneratorResult.TargetMarkerPosition.X - ColorViewModel.RightArrowSize / 2, PathGeneratorResult.TargetMarkerPosition.Y);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ConnectorOrientation.Right:
|
case ConnectorOrientation.Right:
|
||||||
{
|
{
|
||||||
EndPoint = new PointBase(PathGeneratorResult.TargetMarkerPosition.X - ColorViewModel.RightArrowSize, PathGeneratorResult.TargetMarkerPosition.Y - ColorViewModel.RightArrowSize / 2);
|
EndPoint = new PointBase(PathGeneratorResult.TargetMarkerPosition.X - ColorViewModel.RightArrowSize, PathGeneratorResult.TargetMarkerPosition.Y - ColorViewModel.RightArrowSize / 2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ConnectorOrientation.Bottom:
|
case ConnectorOrientation.Bottom:
|
||||||
{
|
{
|
||||||
EndPoint = new PointBase(PathGeneratorResult.TargetMarkerPosition.X - ColorViewModel.RightArrowSize / 2, PathGeneratorResult.TargetMarkerPosition.Y - ColorViewModel.RightArrowSize);
|
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;
|
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)
|
private void DeleteConnection(object args)
|
||||||
{
|
{
|
||||||
if (this.Parent is IDiagramViewModel)
|
if (this.Parent is IDiagramViewModel)
|
||||||
@@ -489,7 +497,10 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
MouseButtonEventArgs mosueArg = ((EventToCommandArgs)parameter).EventArgs as MouseButtonEventArgs;
|
MouseButtonEventArgs mosueArg = ((EventToCommandArgs)parameter).EventArgs as MouseButtonEventArgs;
|
||||||
var position = mosueArg.GetPosition(((EventToCommandArgs)parameter).Sender as IInputElement);
|
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))
|
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)
|
private (PointBase? source, PointBase? target) FindConnectionPoints(PointBase[] route)
|
||||||
{
|
{
|
||||||
if (IsPortless) // Portless
|
if (IsPortless) // Portless
|
||||||
@@ -624,7 +583,58 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
return minPoint;
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,5 +16,15 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
get;
|
get;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override PointBase Position
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new PointBase(Parent.Area.Left + Left, Parent.Area.Top + Top);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override PointBase MiddlePosition => new PointBase(Parent.Area.Left + Left + ConnectorWidth / 2, Parent.Area.Top + Top + ConnectorHeight / 2);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,40 +17,6 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Checks if a property already matches a desired value. Sets the property and
|
|
||||||
/// notifies listeners only when necessary.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">Type of the property.</typeparam>
|
|
||||||
/// <param name="storage">Reference to a property with both getter and setter.</param>
|
|
||||||
/// <param name="value">Desired value for the property.</param>
|
|
||||||
/// <param name="propertyName">Name of the property used to notify listeners. This
|
|
||||||
/// value is optional and can be provided automatically when invoked from compilers that
|
|
||||||
/// support CallerMemberName.</param>
|
|
||||||
/// <returns>True if the value was changed, false if the existing value matched the
|
|
||||||
/// desired value.</returns>
|
|
||||||
protected virtual bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
|
|
||||||
{
|
|
||||||
if (EqualityComparer<T>.Default.Equals(storage, value))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (propertyName == "IsSelected")
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (this.ContainsProperty("IsReadOnly"))
|
|
||||||
{
|
|
||||||
if (object.Equals(this.GetPropertyValue("IsReadOnly"), true))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var old = storage;
|
|
||||||
storage = value;
|
|
||||||
RaisePropertyChanged(propertyName, old, value);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Dictionary<string, object> _oldDic = new Dictionary<string, object>();
|
private Dictionary<string, object> _oldDic = new Dictionary<string, object>();
|
||||||
public void SetOldValue<T>(T value, string propertyName, string guid = null)
|
public void SetOldValue<T>(T value, string propertyName, string guid = null)
|
||||||
{
|
{
|
||||||
@@ -78,6 +44,44 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if a property already matches a desired value. Sets the property and
|
||||||
|
/// notifies listeners only when necessary.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">Type of the property.</typeparam>
|
||||||
|
/// <param name="storage">Reference to a property with both getter and setter.</param>
|
||||||
|
/// <param name="value">Desired value for the property.</param>
|
||||||
|
/// <param name="propertyName">Name of the property used to notify listeners. This
|
||||||
|
/// value is optional and can be provided automatically when invoked from compilers that
|
||||||
|
/// support CallerMemberName.</param>
|
||||||
|
/// <returns>True if the value was changed, false if the existing value matched the
|
||||||
|
/// desired value.</returns>
|
||||||
|
protected virtual bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
|
||||||
|
{
|
||||||
|
if (EqualityComparer<T>.Default.Equals(storage, value))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (propertyName == "IsSelected")
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (this.ContainsProperty("IsReadOnly"))
|
||||||
|
{
|
||||||
|
if (object.Equals(this.GetPropertyValue("IsReadOnly"), true))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (propertyName == "Area")
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
var old = storage;
|
||||||
|
storage = value;
|
||||||
|
RaisePropertyChanged(propertyName, old, value);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if a property already matches a desired value. Sets the property and
|
/// Checks if a property already matches a desired value. Sets the property and
|
||||||
/// notifies listeners only when necessary.
|
/// notifies listeners only when necessary.
|
||||||
@@ -93,11 +97,22 @@ namespace AIStudio.Wpf.DiagramDesigner
|
|||||||
/// desired value.</returns>
|
/// desired value.</returns>
|
||||||
protected virtual bool SetProperty<T>(ref T storage, T value, Action onChanged, [CallerMemberName] string propertyName = null)
|
protected virtual bool SetProperty<T>(ref T storage, T value, Action onChanged, [CallerMemberName] string propertyName = null)
|
||||||
{
|
{
|
||||||
if (EqualityComparer<T>.Default.Equals(storage, value)) return false;
|
if (EqualityComparer<T>.Default.Equals(storage, value)) return false;
|
||||||
|
|
||||||
|
if (propertyName == "IsSelected")
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (this.ContainsProperty("IsReadOnly"))
|
||||||
|
{
|
||||||
|
if (object.Equals(this.GetPropertyValue("IsReadOnly"), true))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var old = storage;
|
||||||
storage = value;
|
storage = value;
|
||||||
onChanged?.Invoke();
|
onChanged?.Invoke();
|
||||||
RaisePropertyChanged(propertyName);
|
RaisePropertyChanged(propertyName, old, value);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user