NodeStudio 0.2.0
dotnet add package NodeStudio --version 0.2.0
NuGet\Install-Package NodeStudio -Version 0.2.0
<PackageReference Include="NodeStudio" Version="0.2.0" />
<PackageVersion Include="NodeStudio" Version="0.2.0" />
<PackageReference Include="NodeStudio" />
paket add NodeStudio --version 0.2.0
#r "nuget: NodeStudio, 0.2.0"
#:package NodeStudio@0.2.0
#addin nuget:?package=NodeStudio&version=0.2.0
#tool nuget:?package=NodeStudio&version=0.2.0
NodeStudio
WPF 节点图编辑器框架 —— 用节点可视化你的逻辑
NodeStudio 帮助你在 .NET 桌面应用中快速构建节点式交互体验:拖一拖节点、连一连线、点一下运行,一个可视化流程就活了。无论是数据流水线、逻辑编排,还是面向最终用户的"低代码"工具,NodeStudio 都为你准备好了画布、引擎与编辑器。
NodeStudio 能做的
- 🧩 所见即所得的编辑:拖拽创建节点、拉线连接、框选、复制粘贴、重命名删除,一切直觉操作
- 🔀 真并行执行:内置 DAG 执行引擎,自动追踪依赖、就绪节点并行运行、失败节点不影响下游
- 📦 子图与模块化:把一组节点打包成"节点块",双击即可进入内部继续编辑——复杂流程也能拆得清清楚楚
- ▶️ 一键运行,放心操作:全局运行/暂停,运行中画布自动进入只读保护(仍可选中与查看),不怕误操作
- 🎛️ 选中即编辑:单击节点,右侧属性面板立即呈现可调参数,改完即生效
- 💾 随存随取:一键保存/加载完整图——节点、连线、参数、子图结构全部保留
- 🌙 一致的深色风格:编辑器、弹窗、菜单、面板统一深色主题,专注不刺眼
快速开始
# 构建
dotnet build NodeStudio.sln
# 运行演示(图形界面)
dotnet run --project TestWpf
# 运行功能测试
dotnet run --project TestConsole
在 TestWpf 演示中:从左侧工具箱拖入节点 → 连线 → 点 ▶ 运行 → 从"文件"菜单导出/导入你的图。
内置节点
引擎自带两个开箱即用的流程节点(工具箱「流程」分类),无需任何代码即可搭建条件分支流程:
节点块
把一组节点打包成可复用模块——双击块即可进入内部编辑器继续编辑,复杂流程拆成清晰的层次结构。
- 「运行」开关输入端口(默认端口,bool):连接后控制块是否执行内部图——
false时整块跳过(标记"未运行"),不连接时块正常运行 - 循环运行:块内部编辑器右上角可配置「循环执行 / 起始 / 结束 / 步长」,让内部图按区间重复执行
- 动态输入/输出端口:在块输入/块输出节点上右键「新增输出 / 新增输入」即可给块加端口
条件节点
按用户设定的条件表达式决定运行哪条后续路线,每个条件对应一个输出端口:
- 添加多个条件(自定义名称 + 表达式),表达式为真时该路线激活;多条同时满足时并行运行
- 典型用法:条件节点输出(bool)连接到节点块的「运行」端口,由条件决定哪个块执行
- 表达式引擎内置:引用输入端口值
[输入1],支持四则/幂运算、比较(>>=<<===!=)、逻辑(&&||!,短路求值)与常用数学函数(abs sqrt sin cos tan pow min max log等),以及常量pi、e - 实时校验:在属性面板输入表达式时即时检查括号、函数名、
[输入名]是否存在、整体是否为判断语句;非法表达式对应的路线不生效且不阻断其他路线
条件节点的输出端口是 bool 类型,只能连接到 bool 输入(如节点块的「运行」端口),从类型上杜绝了误连到数值端口。
内置样式(可复用的控件样式库)
自定义节点控件时可以直接复用框架的深色控件样式——App.xaml 已全局合并样式资源,在你的 XAML 中通过 StaticResource 直接引用即可,无需重复定义:
| 样式 | 控件类型 | 说明 |
|---|---|---|
DialogTextBoxStyle |
TextBox | 深色输入框,聚焦时蓝色边框 |
DarkCheckBoxStyle |
CheckBox | 深色复选框,勾选时蓝色填充 + 白色对勾,悬停高亮 |
DialogButtonStyle |
Button | 深色普通按钮 |
DialogPrimaryButtonStyle |
Button | 深色主按钮(高亮,用于确定类操作) |
IconButtonStyle |
Button | 图标按钮(编辑器操作栏同款) |
DialogCloseButtonStyle |
Button | 弹窗关闭按钮 |
DialogMessageTextStyle |
TextBlock | 弹窗消息文本样式 |
DarkContextMenuStyle |
ContextMenu | 深色右键菜单 |
DarkMenuItemStyle |
MenuItem | 深色菜单项(悬停高亮) |
在自定义节点控件中直接使用:
<ctrl:NodeBaseControl x:Class="MyApp.MyNodeControl"
xmlns:ctrl="clr-namespace:NodeStudio.Controls.Views;assembly=NodeStudio.Controls">
<StackPanel>
<TextBox Text="{Binding Value}" Style="{StaticResource DialogTextBoxStyle}"/>
<CheckBox Content="启用" IsChecked="{Binding Enabled}" Style="{StaticResource DarkCheckBoxStyle}"/>
<Button Content="执行" Command="{Binding RunCommand}" Style="{StaticResource DialogButtonStyle}"/>
</StackPanel>
</ctrl:NodeBaseControl>
样式资源定义在
NodeStudio.Controls/Views/Styles.xaml(含节点状态色/文案转换器),随包分发;编辑器画布、节点、端口、弹窗、菜单与属性面板本身也统一使用这套深色样式。
技术栈
- .NET 8 / WPF(Windows)
- Nodify 节点画布
- MVVM(CommunityToolkit.Mvvm)
- 标准 JSON 序列化,无第三方配置依赖
设计理念
- 面向节点,不碰引擎:你编写节点 ViewModel,端口、连线、执行由框架接管
- 数据流可见:每个节点的运行状态与错误信息一目了然,调试与演示同样轻松
扩展开发:创建你的第一个节点
按下面三步,一个自定义节点就能出现在工具箱、画布、属性面板与序列化中。
1. 定义节点(引擎层)
继承 NodeBase,用 [Node] 特性声明分类与工具箱显示名,构造中声明端口,执行时读写数据:
[Node("基础", "常量")] // (分类, 工具箱显示名)
public class ConstantNode : NodeBase
{
private readonly NodeOutput<int> _output;
/// <summary>可编辑属性——自动被序列化保存/恢复</summary>
public int Value { get; set; } = 1;
public ConstantNode()
{
_output = AddOutput<int>("结果"); // 链式声明输出端口
}
protected override Task ExecuteAsync()
{
_output.SetValue(Value); // 执行时把值写到输出端口
return Task.CompletedTask;
}
public override INode Clone() // 复制粘贴/剪贴板需要
{
var c = new ConstantNode { Value = Value };
Comp.CopyTo(c.Comp); // 复制端口结构
return c;
}
}
- 输入端口:
AddInput<int>("数值A"),执行时input.GetValue()读取(已连接取上游值,未连接取手动值) - 更多参考:
TestConsole/TestNodes.cs中的AddNode(双输入)、DelayNode(异步 + 取消)、FaultNode(失败示例)
2. 创建节点 ViewModel(推荐)
ViewModel 包装节点实例并暴露可绑定属性——这是框架与 UI 交互的入口:
public class ConstantNodeViewModel : NodeViewModel
{
private ConstantNode _node;
public int Value
{
get => _node.Value;
set => SetProperty(_node.Value, value, _node, (n, v) => n.Value = v);
}
// 新建节点
public ConstantNodeViewModel(string name)
{
Subject = _node = new ConstantNode { Name = name };
Init();
}
// 包装已有实例(图反序列化恢复时使用)
public ConstantNodeViewModel(ConstantNode node)
{
Subject = _node = node;
Init();
}
}
3. 操作控件
想让节点被选中时在右侧属性面板显示可编辑界面,继承 NodeBaseControl,用 XAML 搭界面(自动带标题、描述与运行状态三行布局):
<ctrl:NodeBaseControl x:Class="MyApp.ConstantNodeControl"
xmlns:ctrl="clr-namespace:NodeStudio.Controls.Views;assembly=NodeStudio.Controls">
<TextBox Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}"/>
</ctrl:NodeBaseControl>
public class ConstantNodeControl : NodeBaseControl
{
public ConstantNodeControl(ConstantNodeViewModel node) : base(node) => InitializeComponent();
}
// ViewModel 中返回操作控件:
public override Control GetControl() => new ConstantNodeControl(this);
4. 注册自定义 ViewModel(用于导入时恢复操作控件)
NodeViewModelFactory.RegisterVmFactory<ConstantNode>(node => new ConstantNodeViewModel((ConstantNode)node));
注册后,从 JSON 导入图时节点会恢复为你的自定义 ViewModel(而不是通用包装),属性面板与参数不丢失。
完成以上步骤后,程序集自动扫描会把它加入工具箱——无需额外注册。
许可证
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- System.Text.Json (>= 8.0.5)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on NodeStudio:
| Package | Downloads |
|---|---|
|
NodeStudio.Controls
NodeStudio 节点图编辑器控件库(WPF):基于 Nodify 的节点画布、工具箱、属性面板与操作界面,内置深色样式;依赖 NodeStudio 核心库。 |
GitHub repositories
This package is not used by any popular GitHub repositories.