重新设计了创建连线时的逻辑,能够预览连接成功后的外观样式

This commit is contained in:
fengjiayi
2025-01-04 22:20:01 +08:00
parent 665a722f68
commit 702af587f9
20 changed files with 1040 additions and 277 deletions

View File

@@ -23,23 +23,22 @@ namespace Serein.Workbench.Avalonia.Custom.Views
{
private readonly double strokeThickness;
/// <summary>
/// 确定起始坐标和目标坐标、外样式的曲线
/// 确定起始坐标和目标坐标、外样式的曲线
/// </summary>
/// <param name="start">起始坐标</param>
/// <param name="end">结束坐标</param>
/// <param name="left">起始坐标</param>
/// <param name="right">结束坐标</param>
/// <param name="brush">颜色</param>
/// <param name="isDotted">是否为虚线</param>
public ConnectionLineShape(Point start,
Point end,
public ConnectionLineShape(Point left,
Point right,
Brush brush,
bool isDotted = false,
bool isTop = false)
{
this.brush = brush;
startPoint = start;
endPoint = end;
this.leftPoint = left;
this.rightPoint = right;
this.strokeThickness = 4;
InitElementPoint(isDotted, isTop);
InvalidateVisual(); // 触发重绘
@@ -50,9 +49,10 @@ namespace Serein.Workbench.Avalonia.Custom.Views
{
//hitVisiblePen = new Pen(Brushes.Transparent, 1.0); // 初始化碰撞检测线
//hitVisiblePen.Freeze(); // Freeze以提高性能
visualPen = new Pen(brush, 3.0); // 默认可视化Pen
opacity = 1.0d;
var dashStyle = new DashStyle();
//var dashStyle = new DashStyle();
if (isDotted)
{
@@ -71,31 +71,44 @@ namespace Serein.Workbench.Avalonia.Custom.Views
/// <summary>
/// 更新线条落点位置
/// </summary>
/// <param name="start"></param>
/// <param name="end"></param>
public void UpdatePoints(Point start, Point end)
/// <param name="left"></param>
/// <param name="right"></param>
public void UpdatePoint(Point left, Point right, Brush? brush = null)
{
startPoint = start;
endPoint = end;
if(brush is not null)
{
visualPen = new Pen(brush, 3.0); // 默认可视化Pen
}
this.leftPoint = left;
this.rightPoint = right;
InvalidateVisual(); // 触发重绘
}
/// <summary>
/// 更新线条落点位置
/// </summary>
/// <param name="point"></param>
public void UpdateEndPoints(Point point)
/// <param name="right"></param>
public void UpdateRightPoint(Point right, Brush? brush = null)
{
endPoint = point;
if (brush is not null)
{
visualPen = new Pen(brush, 3.0); // 默认可视化Pen
}
this.rightPoint = right;
InvalidateVisual(); // 触发重绘
}
/// <summary>
/// 更新线条起点位置
/// </summary>
/// <param name="point"></param>
public void UpdateStartPoints(Point point)
/// <param name="left"></param>
public void UpdateLeftPoints(Point left, Brush? brush = null)
{
startPoint = point;
if (brush is not null)
{
visualPen = new Pen(brush, 3.0); // 默认可视化Pen
}
this.leftPoint = left;
InvalidateVisual(); // 触发重绘
}
@@ -106,7 +119,7 @@ namespace Serein.Workbench.Avalonia.Custom.Views
public override void Render(DrawingContext drawingContext)
{
// 刷新线条显示位置
DrawBezierCurve(drawingContext, startPoint, endPoint);
DrawBezierCurve(drawingContext, leftPoint, rightPoint);
}
#region
@@ -116,8 +129,8 @@ namespace Serein.Workbench.Avalonia.Custom.Views
private Point leftCenterOfEndLocation; // 起始节点选择右侧边缘中心
//private Pen hitVisiblePen; // 初始化碰撞检测线
private Pen visualPen; // 默认可视化Pen
private Point startPoint; // 连接线的起始节点
private Point endPoint; // 连接线的终点
private Point leftPoint; // 连接线的起始节点
private Point rightPoint; // 连接线的终点
private Brush brush; // 线条颜色
private double opacity; // 透明度
@@ -135,8 +148,8 @@ namespace Serein.Workbench.Avalonia.Custom.Views
private Vector startToEnd;
private int i = 0;
private void DrawBezierCurve(DrawingContext drawingContext,
Point start,
Point end)
Point left,
Point right)
{
// 控制点的计算逻辑
double power = 140; // 控制贝塞尔曲线的“拉伸”强度
@@ -144,7 +157,7 @@ namespace Serein.Workbench.Avalonia.Custom.Views
// 计算轴向向量与起点到终点的向量
//var axis = new Vector(1, 0);
startToEnd = (end.ToVector() - start.ToVector()).NormalizeTo();
startToEnd = (right.ToVector() - left.ToVector()).NormalizeTo();
@@ -163,10 +176,10 @@ namespace Serein.Workbench.Avalonia.Custom.Views
pow = pow > 0 ? 0 : pow;
var k = 1 - pow;
// 如果起点x大于终点x增加额外的偏移量避免重叠
var bias = start.X > end.X ? Math.Abs(start.X - end.X) * 0.25 : 0;
var bias = left.X > right.X ? Math.Abs(left.X - right.X) * 0.25 : 0;
// 控制点的实际计算
c0 = new Point(+(power + bias) * k + start.X, start.Y);
c1 = new Point(-(power + bias) * k + end.X, end.Y);
c0 = new Point(+(power + bias) * k + left.X, left.Y);
c1 = new Point(-(power + bias) * k + right.X, right.Y);
// 准备StreamGeometry以用于绘制曲线
// why can't clearValue()?
@@ -204,8 +217,8 @@ namespace Serein.Workbench.Avalonia.Custom.Views
// streamGeometry.ClearValue("AvaloniaProperty");
using (var context = streamGeometry.Open())
{
context.BeginFigure(start, true); // start point of the bezier-line
context.CubicBezierTo(c0, c1, end, true); // drawing bezier-line
context.BeginFigure(left, true); // start point of the bezier-line
context.CubicBezierTo(c0, c1, right, true); // drawing bezier-line
}
drawingContext.DrawGeometry(null, visualPen, streamGeometry);

View File

@@ -0,0 +1,279 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Shapes;
using Avalonia.Media;
using Avalonia.VisualTree;
using Serein.Library;
using Serein.Script.Node;
using Serein.Workbench.Avalonia.Extension;
using Serein.Workbench.Avalonia.Services;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Color = Avalonia.Media.Color;
using Point = Avalonia.Point;
namespace Serein.Workbench.Avalonia.Custom.Views
{
public class NodeConnectionLineView
{
/// <summary>
/// 线条类别(方法调用)
/// </summary>
public ConnectionInvokeType ConnectionInvokeType { get; set; } = ConnectionInvokeType.IsSucceed;
/// <summary>
/// 线条类别(参数传递)
/// </summary>
public ConnectionArgSourceType ConnectionArgSourceType { get; set; } = ConnectionArgSourceType.GetOtherNodeData;
/// <summary>
/// 画布
/// </summary>
private Canvas Canvas;
/// <summary>
/// 连接线的起点
/// </summary>
private NodeJunctionView? LeftNodeJunctionView;
/// <summary>
/// 连接线的终点
/// </summary>
private NodeJunctionView? RightNodeJunctionView;
/// <summary>
/// 连接时显示的线
/// </summary>
public ConnectionLineShape? ConnectionLineShape { get; private set; }
public NodeConnectionLineView(Canvas canvas,
NodeJunctionView? leftNodeJunctionView,
NodeJunctionView? rightNodeJunctionView)
{
this.Canvas = canvas;
this.LeftNodeJunctionView = leftNodeJunctionView;
this.RightNodeJunctionView = rightNodeJunctionView;
}
/// <summary>
/// 连接到终点
/// </summary>
/// <param name="endNodeJunctionView"></param>
public void ToEnd(NodeJunctionView endNodeJunctionView)
{
if((endNodeJunctionView.JunctionType == JunctionType.NextStep
|| endNodeJunctionView.JunctionType == JunctionType.ReturnData)
&& RightNodeJunctionView is not null
/*&& LeftNodeJunctionView is null*/
/*&& !LeftNodeJunctionView.Equals(endNodeJunctionView)*/)
{
LeftNodeJunctionView = endNodeJunctionView;
RefreshLineDsiplay();
return;
}
else if ((endNodeJunctionView.JunctionType == JunctionType.Execute
|| endNodeJunctionView.JunctionType == JunctionType.ArgData)
&& LeftNodeJunctionView is not null
/*&& RightNodeJunctionView is null*/
/*&& !RightNodeJunctionView.Equals(endNodeJunctionView)*/)
{
RightNodeJunctionView = endNodeJunctionView;
RefreshLineDsiplay();
return;
}
//
//var leftPoint = GetPoint(LeftNodeJunctionView);
//var rightPoint = GetPoint(RightNodeJunctionView);
//var brush = GetBackgrounp();
//ConnectionLineShape.UpdatePoint(leftPoint, rightPoint);
//CreateLineShape(startPoint, endPoint, brush);
}
/// <summary>
/// 刷新线的显示
/// </summary>
public void RefreshLineDsiplay()
{
if(LeftNodeJunctionView is null || RightNodeJunctionView is null)
{
return;
}
var leftPoint = GetPoint(LeftNodeJunctionView);
var rightPoint = GetPoint(RightNodeJunctionView);
if (ConnectionLineShape is null)
{
Debug.WriteLine("创建");
CreateLineShape(leftPoint, rightPoint, GetBackgrounp());
}
else
{
Debug.WriteLine("刷新");
var brush = GetBackgrounp();
ConnectionLineShape.UpdatePoint( leftPoint, rightPoint, brush);
}
}
/// <summary>
/// 刷新临时线的显示
/// </summary>
public void RefreshRightPointOfTempLineDsiplay(Point rightPoint)
{
if(ConnectionLineShape is not null)
{
var brush = GetBackgrounp();
ConnectionLineShape.UpdateRightPoint(rightPoint, brush);
return;
}
if (LeftNodeJunctionView is not null)
{
var leftPoint = GetPoint(LeftNodeJunctionView);
var brush = GetBackgrounp();
CreateLineShape(leftPoint, rightPoint, brush);
}
}
/// <summary>
/// 刷新临时线的显示
/// </summary>
public void RefreshLeftPointOfTempLineDsiplay(Point leftPoint)
{
if(ConnectionLineShape is not null)
{
var brush = GetBackgrounp();
ConnectionLineShape.UpdateLeftPoints(leftPoint, brush);
return;
}
if (RightNodeJunctionView is not null)
{
var rightPoint = GetPoint(RightNodeJunctionView);
var brush = GetBackgrounp();
CreateLineShape(leftPoint, rightPoint, brush);
}
}
private static Point defaultPoint = new Point(0, 0);
int count;
private Point GetPoint(NodeJunctionView nodeJunctionView)
{
var junctionSize = nodeJunctionView.GetTransformedBounds()!.Value.Bounds.Size;
Point junctionPoint;
if (nodeJunctionView.JunctionType == JunctionType.ArgData || nodeJunctionView.JunctionType == JunctionType.Execute)
{
junctionPoint = new Point(junctionSize.Width / 2 - 11, junctionSize.Height / 2); // 选择左侧
}
else
{
junctionPoint = new Point(junctionSize.Width / 2 + 11, junctionSize.Height / 2); // 选择右侧
}
if (nodeJunctionView.TranslatePoint(junctionPoint, Canvas) is Point point)
{
//myData.StartPoint = point;
return point;
}
else
{
return defaultPoint;
}
//var point = nodeJunctionView.TranslatePoint(defaultPoint , Canvas);
//if(point is null)
//{
// return defaultPoint;
//}
//else
//{
// return point.Value;
// }
}
private void CreateLineShape(Point leftPoint, Point rightPoint, Brush brush)
{
ConnectionLineShape = new ConnectionLineShape(leftPoint, rightPoint, brush);
Canvas.Children.Add(ConnectionLineShape);
}
private JunctionOfConnectionType GetConnectionType()
{
return LeftNodeJunctionView.JunctionType.ToConnectyionType();
}
/// <summary>
/// 获取背景颜色
/// </summary>
/// <returns></returns>
public Brush GetBackgrounp()
{
if(LeftNodeJunctionView is null || RightNodeJunctionView is null)
{
return new SolidColorBrush(Color.Parse("#FF0000")); // 没有终点
}
// 判断连接控制点是否匹配
if (!IsCanConnected())
{
return new SolidColorBrush(Color.Parse("#FF0000"));
}
if (GetConnectionType() == JunctionOfConnectionType.Invoke)
{
return ConnectionInvokeType.ToLineColor(); // 调用
}
else
{
return ConnectionArgSourceType.ToLineColor(); // 参数
}
}
public bool IsCanConnected()
{
if (LeftNodeJunctionView is null
|| RightNodeJunctionView is null)
{
return false;
}
if (LeftNodeJunctionView?.MyNode is null
|| LeftNodeJunctionView.MyNode.Equals(RightNodeJunctionView.MyNode))
return false;
if (LeftNodeJunctionView.JunctionType.IsCanConnection(RightNodeJunctionView.JunctionType))
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// 移除线
/// </summary>
public void Remove()
{
if(ConnectionLineShape is null)
{
return;
}
Canvas.Children.Remove(ConnectionLineShape);
}
}
}

View File

@@ -98,6 +98,7 @@ public partial class NodeContainerView : UserControl
{
IsCanvasDragging = false;
IsControlDragging = false;
nodeOperationService.ConnectingData.Reset();
}
};
#endregion
@@ -190,12 +191,11 @@ public partial class NodeContainerView : UserControl
private void NodeContainerView_PointerMoved(object? sender, PointerEventArgs e)
{
// 是否正在连接
var myData = nodeOperationService.ConnectingData;
if (myData.IsCreateing)
{
var isPass = e.JudgePointer(sender, PointerType.Mouse, p => p.IsLeftButtonPressed);
//Debug.WriteLine("canvas ispass = " + isPass);
if (isPass)
{
if (myData.Type == JunctionOfConnectionType.Invoke)
@@ -208,7 +208,9 @@ public partial class NodeContainerView : UserControl
_vm.IsConnectionArgSourceNode = true; // 正在连接节点的调用关系
}
var currentPoint = e.GetPosition(PART_NodeContainer);
//myData.CurrentJunction?.InvalidateVisual();
myData.UpdatePoint(new Point(currentPoint.X - 5, currentPoint.Y - 5));
e.Handled = true;
return;
}

View File

@@ -1,18 +1,14 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Media;
using Serein.Library;
using Serein.Workbench.Avalonia.Views;
using System.Drawing;
using Serein.Library.Api;
using Serein.Workbench.Avalonia.Api;
using Serein.Workbench.Avalonia.Extension;
using System;
using Color = Avalonia.Media.Color;
using Point = Avalonia.Point;
using System.Diagnostics;
using Avalonia.Threading;
using Serein.Workbench.Avalonia.Api;
using Serein.Workbench.Avalonia.Extension;
namespace Serein.Workbench.Avalonia.Custom.Views;
@@ -21,55 +17,6 @@ namespace Serein.Workbench.Avalonia.Custom.Views;
/// </summary>
public class NodeJunctionView : TemplatedControl
{
private readonly INodeOperationService nodeOperationService;
/// <summary>
/// Render方法中控制自绘内容
/// </summary>
protected readonly StreamGeometry StreamGeometry = new StreamGeometry();
/// <summary>
/// 正在查看
/// </summary>
private bool IsPreviewing;
public NodeJunctionView()
{
nodeOperationService = App.GetService<INodeOperationService>();
this.PointerMoved += NodeJunctionView_PointerMoved;
this.PointerExited += NodeJunctionView_PointerExited;
this.PointerPressed += NodeJunctionView_PointerPressed;
this.PointerReleased += NodeJunctionView_PointerReleased;
}
private void NodeJunctionView_PointerReleased(object? sender, PointerReleasedEventArgs e)
{
nodeOperationService.ConnectingData.IsCreateing = false;
}
private void NodeJunctionView_PointerPressed(object? sender, PointerPressedEventArgs e)
{
nodeOperationService.TryCreateConnectionOnJunction(this); // 尝试开始创建
Dispatcher.UIThread.InvokeAsync(InvalidateVisual, DispatcherPriority.Background);
}
/// <summary>
/// 获取到控件信息
/// </summary>
/// <param name="e"></param>
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
//if (e.NameScope.Find("PART_FlipflopMethodInfos") is ListBox p_fm)
//{
// //p_fm.SelectionChanged += ListBox_SelectionChanged;
// //p_fm.PointerExited += ListBox_PointerExited;
//}
}
public static readonly DirectProperty<NodeJunctionView, JunctionType> JunctionTypeProperty =
AvaloniaProperty.RegisterDirect<NodeJunctionView, JunctionType>(nameof(JunctionType), o => o.JunctionType, (o, v) => o.JunctionType = v);
@@ -88,6 +35,160 @@ public class NodeJunctionView : TemplatedControl
get { return myNode; }
set { SetAndRaise(MyNodeProperty, ref myNode, value); }
}
public static readonly DirectProperty<NodeJunctionView, int> ArgIndexProperty =
AvaloniaProperty.RegisterDirect<NodeJunctionView, int>(nameof(ArgIndex), o => o.ArgIndex, (o, v) => o.ArgIndex = v);
private int argIndex;
public int ArgIndex
{
get { return argIndex; }
set { SetAndRaise(ArgIndexProperty, ref argIndex, value); }
}
private readonly INodeOperationService nodeOperationService;
private readonly IFlowEnvironment flowEnvironment;
/// <summary>
/// Render方法中控制自绘内容
/// </summary>
protected readonly StreamGeometry StreamGeometry = new StreamGeometry();
#region
public NodeJunctionView()
{
nodeOperationService = App.GetService<INodeOperationService>();
flowEnvironment = App.GetService<IFlowEnvironment>();
//this.PointerExited += NodeJunctionView_PointerExited;
this.PointerMoved += NodeJunctionView_PointerMoved;
this.PointerPressed += NodeJunctionView_PointerPressed;
this.PointerReleased += NodeJunctionView_PointerReleased;
}
public bool IsPreviewing { get; set; }
private Guid Guid = Guid.NewGuid();
private void NodeJunctionView_PointerMoved(object? sender, PointerEventArgs e)
{
if (!nodeOperationService.ConnectingData.IsCreateing)
return;
if (nodeOperationService.MainCanvas is not InputElement inputElement)
return;
var currentPoint = e.GetPosition(nodeOperationService.MainCanvas);
if (inputElement.InputHitTest(currentPoint) is NodeJunctionView junctionView)
{
RefreshDisplay(junctionView);
}
else
{
var oldNj = nodeOperationService.ConnectingData.CurrentJunction;
if (oldNj is not null)
{
oldNj.IsPreviewing = false;
oldNj.InvalidateVisual();
}
}
}
private void RefreshDisplay(NodeJunctionView junctionView)
{
var oldNj = nodeOperationService.ConnectingData.CurrentJunction;
if (oldNj is not null )
{
if (junctionView.Equals(oldNj))
{
return;
}
oldNj.IsPreviewing = false;
oldNj.InvalidateVisual();
}
nodeOperationService.ConnectingData.CurrentJunction = junctionView;
if (!this.Equals(junctionView))
{
nodeOperationService.ConnectingData.TempLine?.ToEnd(junctionView);
}
junctionView.IsPreviewing = true;
junctionView.InvalidateVisual();
}
/// <summary>
/// 尝试开始创建连接线
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void NodeJunctionView_PointerPressed(object? sender, PointerPressedEventArgs e)
{
nodeOperationService.TryCreateConnectionOnJunction(this); // 尝试开始创建
}
private void NodeJunctionView_PointerReleased(object? sender, PointerReleasedEventArgs e)
{
CheckJunvtion();
nodeOperationService.ConnectingData.Reset();
}
private void CheckJunvtion()
{
var myData = nodeOperationService.ConnectingData;
if(myData.StartJunction is null || myData.CurrentJunction is null)
{
return;
}
if(myData.StartJunction.MyNode is null || myData.CurrentJunction.MyNode is null)
{
return;
}
if (!myData.IsCanConnected())
{
return;
}
var canvas = nodeOperationService.MainCanvas;
#region
if (myData.Type == JunctionOfConnectionType.Invoke)
{
flowEnvironment.ConnectInvokeNodeAsync(myData.StartJunction.MyNode.Guid, myData.CurrentJunction.MyNode.Guid,
myData.StartJunction.JunctionType,
myData.CurrentJunction.JunctionType,
myData.ConnectionInvokeType);
}
#endregion
#region
else if (myData.Type == JunctionOfConnectionType.Arg)
{
var argIndex = 0;
if (myData.StartJunction.JunctionType == JunctionType.ArgData)
{
argIndex = myData.StartJunction.ArgIndex;
}
else if (myData.CurrentJunction.JunctionType == JunctionType.ArgData)
{
argIndex = myData.CurrentJunction.ArgIndex;
}
flowEnvironment.ConnectArgSourceNodeAsync(myData.StartJunction.MyNode.Guid, myData.CurrentJunction.MyNode.Guid,
myData.StartJunction.JunctionType,
myData.CurrentJunction.JunctionType,
myData.ConnectionArgSourceType,
argIndex);
}
#endregion
}
#endregion
#region UI视觉
@@ -101,7 +202,8 @@ public class NodeJunctionView : TemplatedControl
double width = 44;
double height = 26;
var background = GetBackgrounp();
var pen = new Pen(Brushes.Black, 1);
var pen = new Pen(Brushes.Transparent, 1);
//var pen = nodeOperationService.ConnectingData.IsCreateing ? new Pen(background, 1) : new Pen(Brushes.Black, 1);
// 输入连接器的背景
var connectorRect = new Rect(0, 0, width, height);
@@ -132,32 +234,10 @@ public class NodeJunctionView : TemplatedControl
context.LineTo(new Point(triangleCenterX, triangleCenterY + t), true);
context.LineTo(new Point(triangleCenterX, triangleCenterY - t), true);
}
drawingContext.DrawGeometry(background, new Pen(Brushes.Black, 1), pathGeometry);
drawingContext.DrawGeometry(background, pen, pathGeometry);
}
#region
private void NodeJunctionView_PointerExited(object? sender, PointerEventArgs e)
{
if (IsPreviewing)
{
IsPreviewing = false;
Dispatcher.UIThread.InvokeAsync(InvalidateVisual, DispatcherPriority.Background);
}
}
private void NodeJunctionView_PointerMoved(object? sender, PointerEventArgs e)
{
if (!IsPreviewing)
{
IsPreviewing = true;
Dispatcher.UIThread.InvokeAsync(InvalidateVisual, DispatcherPriority.Background);
}
}
#endregion
/// <summary>
@@ -167,38 +247,25 @@ public class NodeJunctionView : TemplatedControl
protected IBrush GetBackgrounp()
{
var myData = nodeOperationService.ConnectingData;
if (!myData.IsCreateing)
if (IsPreviewing == false || !myData.IsCreateing )
{
//Debug.WriteLine($"return color is {Brushes.BurlyWood}");
return new SolidColorBrush(Color.Parse("#76ABEE"));
}
if (myData.IsCanConnected)
if (!myData.IsCanConnected())
{
if (myData.Type == JunctionOfConnectionType.Invoke)
{
return myData.ConnectionInvokeType.ToLineColor();
}
else
{
return myData.ConnectionArgSourceType.ToLineColor();
}
}
else
{
return Brushes.Red;
return new SolidColorBrush(Color.Parse("#FF0000"));
}
if (IsPreviewing)
if (myData.Type == JunctionOfConnectionType.Invoke)
{
//return new SolidColorBrush(Color.Parse("#04FC10"));
return myData.ConnectionInvokeType.ToLineColor(); // 调用
}
else
{
//Debug.WriteLine($"return color is {Brushes.BurlyWood}");
return new SolidColorBrush(Color.Parse("#76ABEE"));
return myData.ConnectionArgSourceType.ToLineColor(); // 参数
}
}
#endregion

View File

@@ -22,7 +22,7 @@
<Grid ColumnDefinitions="20,40,90,auto" Margin="6,0,10,0">
<Grid ColumnDefinitions="20,40,90,*" Margin="6,0,10,0">
<!--<ToolTip.Tip>
<StackPanel>
@@ -31,11 +31,13 @@
</ToolTip.Tip>-->
<!--<ToolTip Background="LightYellow" Foreground="#071042" Content="" />-->
<cv:NodeJunctionView Grid.Column="0" JunctionType="ArgData" MyNode="{Binding ParameterDetails.NodeModel}" Width="30" Height="15" Margin="2" HorizontalAlignment="Center" VerticalAlignment="Center" />
<cv:NodeJunctionView Grid.Column="0" JunctionType="ArgData" ArgIndex="{Binding ParameterDetails.Index}" MyNode="{Binding ParameterDetails.NodeModel}" Width="30" Height="15" Margin="2" HorizontalAlignment="Center" VerticalAlignment="Center" />
<!--指定参数-->
<CheckBox Grid.Column="1" IsChecked="{Binding ParameterDetails.IsExplicitData, Mode=TwoWay}" HorizontalAlignment="Center" VerticalAlignment="Center" >
</CheckBox>
<!--<TextBlock Grid.Column="2" Text="{Binding ParameterDetails.Index, StringFormat='arg{0} '}" FontSize="14" HorizontalAlignment="Center" VerticalAlignment="Center" />-->
<!--参数名称-->
<TextBlock Grid.Column="2" Text="{Binding ParameterDetails.Name}" FontSize="14"
HorizontalAlignment="Left" VerticalAlignment="Center"
ToolTip.Placement="Bottom" ToolTip.VerticalOffset="6">
@@ -45,12 +47,16 @@
</StackPanel>
</ToolTip.Tip>
</TextBlock>
<TextBlock Grid.Column="3" IsVisible="{Binding IsVisibleA}" FontSize="14" Text=" [ 自动取参 ]" MinWidth="100" MaxWidth="300" HorizontalAlignment="Left" VerticalAlignment="Center" />
<TextBox Grid.Column="3" IsVisible="{Binding IsVisibleB}" FontSize="14" Text="{Binding ParameterDetails.DataValue, Mode=TwoWay}" MinWidth="100" MaxWidth="300" HorizontalAlignment="Left" VerticalAlignment="Center" />
<!--参数内容-->
<TextBlock Grid.Column="3" IsVisible="{Binding IsVisibleA}" FontSize="14" Text=" [ 自动取参 ]"
MinWidth="120" MaxWidth="300" HorizontalAlignment="Left" VerticalAlignment="Center" />
<TextBox Grid.Column="3" IsVisible="{Binding IsVisibleB}" FontSize="14" Text="{Binding ParameterDetails.DataValue, Mode=TwoWay}"
MinWidth="120" MaxWidth="300" HorizontalAlignment="Left" VerticalAlignment="Center" />
<ComboBox Grid.Column="3" IsVisible="{Binding IsVisibleC}"
ItemsSource="{Binding ParameterDetails.Items}"
SelectedValue="{Binding ParameterDetails.DataValue,Mode=OneTime}"
MinWidth="100" MaxWidth="300">
MinWidth="120" MaxWidth="300"
HorizontalAlignment="Left" VerticalAlignment="Center">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" FontFamily="{Binding}" FontSize="14"/>