1. 重新设计了Generate项目及相关特性的命名,避免与其他类型混淆。

2. 补充了部分注释。
3. 修改了删除容器节点时,容器内子节点未正确删除的问题。
This commit is contained in:
fengjiayi
2025-07-30 21:15:07 +08:00
parent 93148b11a5
commit 152077e9b5
188 changed files with 2713 additions and 1406 deletions

View File

@@ -14,7 +14,7 @@ namespace Serein.Workbench.Node
/// <summary>
/// 约束一个节点应该有哪些控制点
/// </summary>
public interface INodeJunction
internal interface INodeJunction
{
/// <summary>
/// 方法执行入口控制点

View File

@@ -35,7 +35,7 @@ namespace Serein.Workbench.Node.View
/// </summary>
public class ConnectionLineShape : Shape
{
private readonly double strokeThickness;
//private readonly double strokeThickness;
private readonly LineType lineType;
@@ -47,6 +47,7 @@ namespace Serein.Workbench.Node.View
/// <param name="end">结束坐标</param>
/// <param name="brush">颜色</param>
/// <param name="isDotted">是否为虚线</param>
/// <param name="isTop">元素是否在画布上置顶</param>
public ConnectionLineShape(LineType lineType,
Point start,
Point end,
@@ -58,7 +59,7 @@ namespace Serein.Workbench.Node.View
this.brush = brush;
startPoint = start;
endPoint = end;
this.strokeThickness = 4;
//this.strokeThickness = 4;
InitElementPoint(isDotted, isTop);
_ = Task.Run(async () =>
@@ -72,6 +73,11 @@ namespace Serein.Workbench.Node.View
}
/// <summary>
/// 初始化连接线元素点
/// </summary>
/// <param name="isDotted"></param>
/// <param name="isTop"></param>
public void InitElementPoint(bool isDotted , bool isTop = false)
{
hitVisiblePen = new Pen(Brushes.Transparent, 1.0); // 初始化碰撞检测线
@@ -148,8 +154,8 @@ namespace Serein.Workbench.Node.View
#region
private readonly StreamGeometry streamGeometry = new StreamGeometry();
private Point rightCenterOfStartLocation; // 目标节点选择左侧边缘中心
private Point leftCenterOfEndLocation; // 起始节点选择右侧边缘中心
//private Point rightCenterOfStartLocation; // 目标节点选择左侧边缘中心
//private Point leftCenterOfEndLocation; // 起始节点选择右侧边缘中心
private Pen hitVisiblePen; // 初始化碰撞检测线
private Pen visualPen; // 默认可视化Pen
private Point startPoint; // 连接线的起始节点
@@ -158,8 +164,16 @@ namespace Serein.Workbench.Node.View
private double opacity; // 透明度
double linkSize; // 根据缩放比例调整线条粗细
/// <summary>
/// 定义几何形状
/// </summary>
protected override Geometry DefiningGeometry => streamGeometry;
/// <summary>
/// 更新线条颜色
/// </summary>
/// <param name="brush"></param>
public void UpdateLineColor(Brush brush)
{
visualPen = new Pen(brush, 3.0); // 默认可视化Pen

View File

@@ -46,7 +46,7 @@ namespace Serein.Workbench.Node.View
/// <summary>
/// 入参控件
/// </summary>
public class ParamsArgControl: Shape
internal class ParamsArgControl: Shape
{
public ParamsArgControl()
{
@@ -172,7 +172,7 @@ namespace Serein.Workbench.Node.View
public abstract class JunctionControlBase : Shape
internal abstract class JunctionControlBase : Shape
{
private readonly FlowNodeService flowNodeService;
protected JunctionControlBase()
@@ -262,16 +262,12 @@ namespace Serein.Workbench.Node.View
/// <summary>
/// 禁止连接
/// </summary>
private bool IsConnectionDisable;
/// <summary>
/// 处理鼠标悬停状态
/// </summary>
private bool _isMouseOver;
public bool IsMouseOver
public new bool IsMouseOver
{
get => _isMouseOver;
set

View File

@@ -14,7 +14,7 @@ namespace Serein.Workbench.Node.View
{
#region Model
public class MyLine
internal class MyLine
{
public MyLine(Canvas canvas, ConnectionLineShape line)
{
@@ -32,7 +32,7 @@ namespace Serein.Workbench.Node.View
}
}
public class ConnectingData
internal class ConnectingData
{
/// <summary>
@@ -42,11 +42,11 @@ namespace Serein.Workbench.Node.View
/// <summary>
/// 起始控制点
/// </summary>
public JunctionControlBase StartJunction { get; set; }
public JunctionControlBase? StartJunction { get; set; }
/// <summary>
/// 当前的控制点
/// </summary>
public JunctionControlBase CurrentJunction { get; set; }
public JunctionControlBase? CurrentJunction { get; set; }
/// <summary>
/// 开始坐标
/// </summary>
@@ -54,7 +54,7 @@ namespace Serein.Workbench.Node.View
/// <summary>
/// 线条样式
/// </summary>
public MyLine MyLine { get; set; }
public MyLine? MyLine { get; set; }
/// <summary>
/// 线条类别(方法调用)
@@ -68,7 +68,7 @@ namespace Serein.Workbench.Node.View
/// <summary>
/// 判断当前连接类型
/// </summary>
public JunctionOfConnectionType Type => StartJunction.JunctionType.ToConnectyionType();
public JunctionOfConnectionType Type => StartJunction?.JunctionType.ToConnectyionType() ?? JunctionOfConnectionType.None;
/// <summary>
@@ -113,11 +113,11 @@ namespace Serein.Workbench.Node.View
if (StartJunction.JunctionType == Library.JunctionType.Execute
|| StartJunction.JunctionType == Library.JunctionType.ArgData)
{
MyLine.Line.UpdateStartPoints(point);
MyLine?.Line.UpdateStartPoints(point);
}
else
{
MyLine.Line.UpdateEndPoints(point);
MyLine?.Line.UpdateEndPoints(point);
}
}

View File

@@ -5,7 +5,7 @@ using Serein.Library;
namespace Serein.Workbench.Node.View
{
public class ArgJunctionControl : JunctionControlBase
internal class ArgJunctionControl : JunctionControlBase
{
public ArgJunctionControl()
{

View File

@@ -6,7 +6,7 @@ using Serein.Library;
namespace Serein.Workbench.Node.View
{
public class ExecuteJunctionControl : JunctionControlBase
internal class ExecuteJunctionControl : JunctionControlBase
{
public ExecuteJunctionControl()
{

View File

@@ -6,7 +6,7 @@ using Serein.Library;
namespace Serein.Workbench.Node.View
{
public class NextStepJunctionControl : JunctionControlBase
internal class NextStepJunctionControl : JunctionControlBase
{
//public override JunctionType JunctionType { get; } = JunctionType.NextStep;
public NextStepJunctionControl()

View File

@@ -6,7 +6,7 @@ using Serein.Library;
namespace Serein.Workbench.Node.View
{
public class ResultJunctionControl : JunctionControlBase
internal class ResultJunctionControl : JunctionControlBase
{
public ResultJunctionControl()
{

View File

@@ -13,7 +13,7 @@ namespace Serein.Workbench.Node.View
/// <summary>
/// 节点控件基类(控件)
/// </summary>
public abstract class NodeControlBase : UserControl //, IDynamicFlowNode
public abstract class NodeControlBase : UserControl
{
/// <summary>
/// 节点所在的画布(以后需要将画布封装出来,实现多画布的功能)
@@ -34,12 +34,18 @@ namespace Serein.Workbench.Node.View
public NodeControlViewModelBase ViewModel { get; set; }
/// <summary>
/// 节点控件基类,所有节点控件都需要继承这个类
/// </summary>
protected NodeControlBase()
{
this.Background = Brushes.Transparent;
}
/// <summary>
/// 节点控件基类,所有节点控件都需要继承这个类
/// </summary>
/// <param name="viewModelBase"></param>
protected NodeControlBase(NodeControlViewModelBase viewModelBase)
{
ViewModel = viewModelBase;
@@ -85,7 +91,7 @@ namespace Serein.Workbench.Node.View
/// 添加与该节点有关的连接后,记录下来
/// </summary>
/// <param name="connection"></param>
public void AddCnnection(ConnectionControl connection)
internal void AddCnnection(ConnectionControl connection)
{
connectionControls.Add(connection);
}
@@ -94,7 +100,7 @@ namespace Serein.Workbench.Node.View
/// 删除了连接之后,还需要从节点中的记录移除
/// </summary>
/// <param name="connection"></param>
public void RemoveConnection(ConnectionControl connection)
internal void RemoveConnection(ConnectionControl connection)
{
connectionControls.Remove(connection);
connection.Remove(); // 主动删除连接
@@ -163,7 +169,7 @@ namespace Serein.Workbench.Node.View
return null;
}
protected static JunctionControlBase[] GetArgJunction(NodeControlBase nodeControl, MethodDetailsControl methodDetailsControl)
internal static JunctionControlBase[] GetArgJunction(NodeControlBase nodeControl, MethodDetailsControl methodDetailsControl)
{
// 获取 MethodDetailsControl 实例
try

View File

@@ -17,14 +17,16 @@ namespace Serein.Workbench.Node.ViewModel
///// </summary>
public IFlowNode NodeModel { get; }
/// <summary>
/// 节点控制器的基类
/// </summary>
/// <param name="nodeModel"></param>
public NodeControlViewModelBase(IFlowNode nodeModel)
{
NodeModel = nodeModel;
}
/// <summary>
/// 工作台预览基本节点时,避免其中的文本框响应拖拽事件导致卡死
/// </summary>
@@ -32,13 +34,5 @@ namespace Serein.Workbench.Node.ViewModel
private bool isEnabledOnView = true;
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

View File

@@ -14,6 +14,10 @@ namespace Serein.Workbench.Node.View
/// </summary>
public partial class ActionNodeControl : NodeControlBase, INodeJunction
{
/// <summary>
/// 构造函数传入ViewModel
/// </summary>
/// <param name="viewModel"></param>
public ActionNodeControl(ActionNodeControlViewModel viewModel) : base(viewModel)
{
DataContext = viewModel;

View File

@@ -10,6 +10,9 @@ namespace Serein.Workbench.Node.View
/// </summary>
public partial class ConditionNodeControl : NodeControlBase, INodeJunction
{
/// <summary>
/// 条件节点控件(用于条件控件)
/// </summary>
public ConditionNodeControl() : base()
{
@@ -22,6 +25,11 @@ namespace Serein.Workbench.Node.View
InitializeComponent();
}
/// <summary>
/// 条件节点控件(用于条件控件)
/// </summary>
/// <param name="viewModel"></param>
public ConditionNodeControl(ConditionNodeControlViewModel viewModel):base(viewModel)
{
DataContext = viewModel;

View File

@@ -18,7 +18,9 @@ namespace Serein.Workbench.Node.View
{
#region
/// <summary>
/// 连接点类型
/// </summary>
public class ConnectionModelBase
{
@@ -48,8 +50,14 @@ namespace Serein.Workbench.Node.View
}
/// <summary>
/// 连接点类型
/// </summary>
public interface IJunctionNode
{
/// <summary>
/// 连接点所属Guid
/// </summary>
string BoundNodeGuid { get; }
}
@@ -73,26 +81,26 @@ namespace Serein.Workbench.Node.View
}
@@ -104,7 +112,7 @@ namespace Serein.Workbench.Node.View
/// <summary>
/// 连接控件,表示控件的连接关系
/// </summary>
public class ConnectionControl
internal class ConnectionControl
{
/// <summary>
/// 所在的画布
@@ -155,7 +163,9 @@ namespace Serein.Workbench.Node.View
/// </summary>
/// <param name="Canvas"></param>
/// <param name="invokeType"></param>
public ConnectionControl(Canvas Canvas,
/// <param name="Start"></param>
/// <param name="End"></param>
internal ConnectionControl(Canvas Canvas,
ConnectionInvokeType invokeType,
JunctionControlBase Start,
JunctionControlBase End)
@@ -169,10 +179,15 @@ namespace Serein.Workbench.Node.View
}
/// <summary>
/// 关于入参
/// 关于入参
/// </summary>
/// <param name="LineType"></param>
/// <param name="Canvas"></param>
/// <param name="Type"></param>
/// <param name="argIndex"></param>
/// <param name="argSourceType"></param>
/// <param name="Start"></param>
/// <param name="End"></param>
/// <param name="nodeJunction"></param>
public ConnectionControl(LineType LineType,
Canvas Canvas,
int argIndex,

View File

@@ -10,6 +10,9 @@ namespace Serein.Workbench.Node.View
/// </summary>
public partial class ExpOpNodeControl : NodeControlBase, INodeJunction
{
/// <summary>
/// 表达式操作节点控件
/// </summary>
public ExpOpNodeControl() : base()
{
// 窗体初始化需要
@@ -20,6 +23,11 @@ namespace Serein.Workbench.Node.View
DataContext = ViewModel;
InitializeComponent();
}
/// <summary>
/// 表达式操作节点控件构造函数,使用指定的 ViewModel 初始化
/// </summary>
/// <param name="viewModel"></param>
public ExpOpNodeControl(ExpOpNodeControlViewModel viewModel) :base(viewModel)
{
DataContext = viewModel;

View File

@@ -9,6 +9,10 @@ namespace Serein.Workbench.Node.View
/// </summary>
public partial class FlipflopNodeControl : NodeControlBase, INodeJunction
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="viewModel"></param>
public FlipflopNodeControl(FlipflopNodeControlViewModel viewModel) : base(viewModel)
{
DataContext = viewModel;

View File

@@ -14,6 +14,10 @@ namespace Serein.Workbench.Node.View
public partial class FlowCallNodeControl : NodeControlBase, INodeJunction
{
private new FlowCallNodeControlViewModel ViewModel { get; set; }
/// <summary>
/// 流程接口节点控件构造函数
/// </summary>
public FlowCallNodeControl()
{
var env = App.GetService<IFlowEnvironment>();
@@ -23,6 +27,11 @@ namespace Serein.Workbench.Node.View
base.ViewModel.NodeModel.DisplayName = "[流程接口]";
InitializeComponent();
}
/// <summary>
/// 流程接口节点控件构造函数传入ViewModel
/// </summary>
/// <param name="viewModel"></param>
public FlowCallNodeControl(FlowCallNodeControlViewModel viewModel) : base(viewModel)
{
DataContext = viewModel;

View File

@@ -13,10 +13,14 @@ namespace Serein.Workbench.Node.View
{
private readonly GlobalDataNodeControlViewModel viewModel;
/// <summary>
/// 全局数据控件构造函数,使用默认的全局数据节点模型
/// </summary>
public GlobalDataControl() : base()
{
// 窗体初始化需要
var env = App.GetService<IFlowEnvironment>();
viewModel = new GlobalDataNodeControlViewModel(new SingleGlobalDataNode(env));
base.ViewModel = new GlobalDataNodeControlViewModel(new SingleGlobalDataNode(env));
base.ViewModel.IsEnabledOnView = false;
base.ViewModel.NodeModel.DisplayName = "[全局数据]";
@@ -24,6 +28,11 @@ namespace Serein.Workbench.Node.View
InitializeComponent();
}
/// <summary>
/// 全局数据控件构造函数,使用指定的全局数据节点模型
/// </summary>
/// <param name="viewModel"></param>
public GlobalDataControl(GlobalDataNodeControlViewModel viewModel) : base(viewModel)
{
DataContext = viewModel;
@@ -54,6 +63,11 @@ namespace Serein.Workbench.Node.View
JunctionControlBase[] INodeJunction.ArgDataJunction => throw new NotImplementedException();
/// <summary>
/// 放置节点控件到全局数据面板中
/// </summary>
/// <param name="nodeControl"></param>
/// <returns></returns>
public bool PlaceNode(NodeControlBase nodeControl)
{
if (GlobalDataPanel.Children.Contains(nodeControl))
@@ -65,6 +79,11 @@ namespace Serein.Workbench.Node.View
return true;
}
/// <summary>
/// 从全局数据面板中取出节点控件
/// </summary>
/// <param name="nodeControl"></param>
/// <returns></returns>
public bool TakeOutNode(NodeControlBase nodeControl)
{
if (!GlobalDataPanel.Children.Contains(nodeControl))
@@ -75,6 +94,9 @@ namespace Serein.Workbench.Node.View
return true;
}
/// <summary>
/// 取出所有节点控件(用于删除容器)
/// </summary>
public void TakeOutAll()
{
GlobalDataPanel.Children.Clear();

View File

@@ -58,7 +58,6 @@ namespace Serein.Workbench.Node.View
JunctionControlBase INodeJunction.ReturnDataJunction => throw new Exception();
public JunctionControlBase[] ArgDataJunction => [];
JunctionControlBase[] INodeJunction.ArgDataJunction => [];
}
}

View File

@@ -26,9 +26,11 @@ namespace Serein.Workbench.Node.View
public partial class ScriptNodeControl : NodeControlBase , INodeJunction
{
private ScriptNodeControlViewModel viewModel => (ScriptNodeControlViewModel)ViewModel;
private DispatcherTimer _debounceTimer; // 用于延迟更新
private bool _isUpdating = false; // 防止重复更新
/// <summary>
/// BaseNodesView.xaml 准备节点预览入口
/// </summary>
public ScriptNodeControl()
{
@@ -39,6 +41,11 @@ namespace Serein.Workbench.Node.View
viewModel.NodeModel.DisplayName = "[脚本节点]";
InitializeComponent();
}
/// <summary>
/// 流程运行环境创建节点入口
/// </summary>
/// <param name="viewModel"></param>
public ScriptNodeControl(ScriptNodeControlViewModel viewModel) : base(viewModel)
{
DataContext = viewModel;

View File

@@ -30,25 +30,23 @@ namespace Serein.Workbench.Node.View
InitializeComponent();
}
public UINodeControl(UINodeControlViewModel viewModel) : base(viewModel)
internal UINodeControl(UINodeControlViewModel viewModel) : base(viewModel)
{
ViewModel = viewModel;
DataContext = viewModel;
ViewModel.NodeModel.DisplayName = "[流程UI]";
InitializeComponent();
}
public JunctionControlBase ExecuteJunction => this.ExecuteJunctionControl;
JunctionControlBase INodeJunction.ExecuteJunction => this.ExecuteJunctionControl;
public JunctionControlBase NextStepJunction => throw new NotImplementedException();
JunctionControlBase INodeJunction.NextStepJunction => throw new NotImplementedException();
public JunctionControlBase[] ArgDataJunction => throw new NotImplementedException();
JunctionControlBase[] INodeJunction.ArgDataJunction => throw new NotImplementedException();
public JunctionControlBase ReturnDataJunction => throw new NotImplementedException();
JunctionControlBase INodeJunction.ReturnDataJunction => throw new NotImplementedException();
private void NodeControlBase_Loaded(object sender, RoutedEventArgs e)

View File

@@ -4,8 +4,15 @@ using Serein.Workbench.Node.View;
namespace Serein.Workbench.Node.ViewModel
{
/// <summary>
/// ActionNodeControlViewModel 类用于表示单动作节点的控制视图模型。
/// </summary>
public class ActionNodeControlViewModel : NodeControlViewModelBase
{
/// <summary>
/// 构造一个新的 ActionNodeControlViewModel 实例。
/// </summary>
/// <param name="node"></param>
public ActionNodeControlViewModel(SingleActionNode node) : base(node)
{
// this.NodelModel = node;

View File

@@ -10,7 +10,7 @@ namespace Serein.Workbench.Node.ViewModel
public class ConditionNodeControlViewModel : NodeControlViewModelBase
{
public new SingleConditionNode NodeModel { get; }
private new SingleConditionNode NodeModel { get; }
/// <summary>
/// 是否为自定义参数

View File

@@ -4,9 +4,15 @@ using Serein.Workbench.Node.View;
namespace Serein.Workbench.Node.ViewModel
{
/// <summary>
/// 表达式操作节点控制视图模型
/// </summary>
public class ExpOpNodeControlViewModel: NodeControlViewModelBase
{
public new SingleExpOpNode NodeModel { get; }
/// <summary>
/// 对应的表达式操作节点模型
/// </summary>
public new SingleExpOpNode NodeModel { get; }
//public string Expression
//{
@@ -18,6 +24,10 @@ namespace Serein.Workbench.Node.ViewModel
// }
//}
/// <summary>
/// 表达式操作节点控制视图模型构造函数
/// </summary>
/// <param name="nodeModel"></param>
public ExpOpNodeControlViewModel(SingleExpOpNode nodeModel) : base(nodeModel)
{

View File

@@ -4,10 +4,21 @@ using Serein.Workbench.Node.View;
namespace Serein.Workbench.Node.ViewModel
{
/// <summary>
/// 单触发器节点控制视图模型
/// </summary>
public class FlipflopNodeControlViewModel : NodeControlViewModelBase
{
public new SingleFlipflopNode NodelModel { get;}
public FlipflopNodeControlViewModel(SingleFlipflopNode node) : base(node)
/// <summary>
/// 单触发器节点模型
/// </summary>
public SingleFlipflopNode NodelModel { get;}
/// <summary>
/// 构造一个新的单触发器节点控制视图模型实例。
/// </summary>
/// <param name="node"></param>
public FlipflopNodeControlViewModel(SingleFlipflopNode node) : base(node)
{
this.NodelModel = node;
}

View File

@@ -50,6 +50,10 @@ namespace Serein.Workbench.Node.ViewModel
private readonly FlowNodeService flowNodeService;
private readonly IFlowEEForwardingService flowEEForwardingService;
/// <summary>
/// 流程接口节点构造函数
/// </summary>
/// <param name="node"></param>
public FlowCallNodeControlViewModel(SingleFlowCallNode node) : base(node)
{
this.FlowCallNode = node;

View File

@@ -5,9 +5,12 @@ using System.Windows.Input;
namespace Serein.Workbench.Node.ViewModel
{
/// <summary>
/// 全局数据节点控制视图模型
/// </summary>
public class GlobalDataNodeControlViewModel : NodeControlViewModelBase
{
private SingleGlobalDataNode NodeModel => (SingleGlobalDataNode)base.NodeModel;
private new SingleGlobalDataNode NodeModel => (SingleGlobalDataNode)base.NodeModel;
/// <summary>
/// 复制全局数据表达式
@@ -19,7 +22,10 @@ namespace Serein.Workbench.Node.ViewModel
/// </summary>
public ICommand CommandRefreshData { get; }
/// <summary>
/// 全局数据节点控制视图模型构造函数
/// </summary>
/// <param name="node"></param>
public GlobalDataNodeControlViewModel(SingleGlobalDataNode node) : base(node)
{
CommandCopyDataExp = new RelayCommand( o =>

View File

@@ -6,9 +6,12 @@ using System.Windows.Input;
namespace Serein.Workbench.Node.ViewModel
{
/// <summary>
/// 动态脚本节点控制视图模型
/// </summary>
public class NetScriptNodeControlViewModel : NodeControlViewModelBase
{
private SingleNetScriptNode NodeModel => (SingleNetScriptNode)base.NodeModel;
private new SingleNetScriptNode NodeModel => (SingleNetScriptNode)base.NodeModel;
public string Tips
{
@@ -45,22 +48,12 @@ public class FlowLibrary
}
}";
CommandOpenScriptEdit = new RelayCommand(async o =>
CommandOpenScriptEdit = new RelayCommand(o =>
{
DynamicCompilerView dynamicCompilerView = new DynamicCompilerView();
dynamicCompilerView.ScriptCode = this.Script ;
dynamicCompilerView.OnCompileComplete = OnCompileComplete;
dynamicCompilerView.ShowDialog();
//try
//{
// var result = await NodeModel.ExecutingAsync(new Library.DynamicContext(nodeModel.Env));
// nodeModel.Env.WriteLine(InfoType.INFO, result?.ToString());
//}
//catch (Exception ex)
//{
// nodeModel.Env.WriteLine(InfoType.ERROR, ex.ToString());
//}
});
NodeModel1 = nodeModel;
}
@@ -86,6 +79,10 @@ public class FlowLibrary
/// 打开编辑窗口
/// </summary>
public ICommand CommandOpenScriptEdit { get; }
/// <summary>
/// 节点模型
/// </summary>
public NodeModelBase NodeModel1 { get; }
}
}

View File

@@ -13,9 +13,13 @@ using System.Windows.Input;
namespace Serein.Workbench.Node.ViewModel
{
/// <summary>
/// 脚本节点控制视图模型
/// </summary>
public class ScriptNodeControlViewModel : NodeControlViewModelBase
{
private SingleScriptNode NodeModel => (SingleScriptNode)base.NodeModel;
private new SingleScriptNode NodeModel => (SingleScriptNode)base.NodeModel;
public string? Script
{

View File

@@ -12,9 +12,13 @@ using System.Windows.Controls;
namespace Serein.Workbench.Node.ViewModel
{
/// <summary>
/// UI节点控制器视图模型
/// </summary>
public partial class UINodeControlViewModel : NodeControlViewModelBase
{
private SingleUINode NodeModel => (SingleUINode)base.NodeModel;
private new SingleUINode NodeModel => (SingleUINode)base.NodeModel;
//public IEmbeddedContent Adapter => NodeModel.Adapter;
/// <summary>