STNodeEditor is a node editor for .NET that draws itself with GDI+
一款基于.Net WinForm的节点编辑器 纯GDI+绘制 使用方式非常简洁 提供了丰富的属性以及事件 可以非常方便的完成节点之间数据的交互及通知 大量的虚函数供开发者重写具有很高的自由性
At a glance
- What is it?
- STNodeEditor is a node editor control for .NET WinForms, written with GDI+ and no third party dependencies, packaged as the ST.Library.UI NuGet package. Its three parts are a tree of available nodes, a property grid and the editor canvas, and the data model is a set of typed connection options per node. The README also says plainly that version 2.0 ships no ready-made controls, only the base class, and that version 3.0 was still in progress.
- Who is it for?
- Adopt STNodeEditor if you are building a .NET WinForms tool whose execution flow should be visible and editable at runtime rather than hard coded, and if you want a node canvas without pulling in a large graph framework.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 76 days ago.
- What is it written in?
- Mainly C#, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A node canvas with no dependencies and a 100 KB footprint
STNodeEditor is a node editor built on .NET WinForms, drawn with GDI, with no dependency libraries at all and a size of just over 100 KB. That combination is the whole pitch, and it is unusual.
The project description calls it a lightweight and powerful node editor, implemented in pure GDI, using it very simply, providing rich properties and events so that data exchange and notification between nodes is convenient, and offering a large number of virtual functions for developers to override, which gives a high degree of freedom.
The environment line is short: VisualStudio 2010 and .NET 3.5. The badges in the README match, with a VisualStudio 2010 badge, a .NET 3.5 badge and a NuGet badge pointing at the ST.Library.UI package. The stated installation command is:
PM> Install-Package ST.Library.UI -Version 2.0.0The no dependency claim is worth taking seriously for a control library. A graph editor that drags in a rendering framework, a layout engine and a dependency injection container is a heavy thing to add to a desktop application, especially one that has to keep working on a machine with an old .NET runtime. Here the drawing is GDI, which is in the framework, and the package is small enough to read.
The audience is the Windows desktop developer who wants to let a user assemble a pipeline at runtime. The repository layout supports that reading: a WinNodeEditorDemo/ project, a WpfNodeEdittorDemo/ project, a NativeWpf/ directory, the library itself in ST.Library.UI/, a docs/ directory and a solution file, WinNodeEditorTest.sln.
Three encounters with node editors, then an implementation
The README opens with a short origin story, and it explains the design more than a feature list would.
The author first met a node editor while researching radio security, and came across GNURadio. The reaction recorded in the text is the one of a developer who does not understand what he is looking at. A second meeting came with Blender, which the author had started to learn while stuck at home, and the reaction was the opposite: so this thing can be used in so many ways, and it is convenient. A third came with DaVinci Resolve, and that contact multiplied the appreciation for the idea, with the conclusion that anything that can be modularised and turned into a process can be turned into nodes.
That progression is why the library looks the way it does. GNURadio is a signal processing flow, Blender is a node based tool for a general application, and DaVinci is a node based tool for media. The library takes the general idea rather than any one of them.
The project home page is at DebugST.github.io/STNodeEditor, with the tutorial documentation in Chinese at doc_cn.html and the English tutorials and API reference at doc_en.html. There is also a mail address for the author and a separate project, STJson, which the README says the current project needs.
The repository listing also shows V3_CN.md and V3_EN.md, the Chinese and English progress notes for version 3.0, and the README states that the 3.0 version has entered scheduled development with progress updated synchronously, referring to those two files for details.
TreeView, PropertyGrid and NodeEditor make up the framework
The README states that STNodeEditor contains three parts, TreeView, PropertyGrid and NodeEditor, and that together they form a complete usable framework.
The motivation is described in the section on using your functions like a flowchart. In many development processes you design a flowchart for the whole program, containing the functional modules and the execution flow, and then implement each piece. The problems that follow are described plainly. The execution flow of the program may end up hard coded into the program. If one day you need to change the execution order, or add or remove an execution module, a developer has to edit and recompile the code. And the calls between the functional modules also have to be coded and scheduled by the developer, which increases development cost.
The three components answer those three problems.
TreeView is where the executable functions are encoded as nodes, and the tree is responsible for displaying and retrieving them. Nodes in the tree can be dragged directly into the NodeEditor.
PropertyGrid is compared to the property window used in WinForms development. A node can have properties, and the author treats a node during the design process as a Form, so that a developer has almost no learning curve.
NodeEditor is the place where the user assembles their own execution flow, making the flow of the functional modules visual.
The design goal of the PropertyGrid is what tells you this is a serious control rather than a demo. If nodes have editable properties, then a runtime pipeline is configurable, and the node editor becomes a user interface for a program rather than a picture of one.
Creating a node is subclassing STNode and overriding OnCreate
The usage section says you can create a node much as you would create a Form, and the first example is the demonstration of that idea.
public class MyNode : STNode
{
public MyNode() { //等同于 [override void Oncreate(){}]
this.Title = "MyNode";
this.TitleColor = Color.FromArgb(200, Color.Goldenrod);
this.AutoSize = false;
this.Size = new Size(100, 100);
var ctrl = new STNodeControl();
ctrl.Text = "Button";
ctrl.Location = new Point(10, 10);
this.Controls.Add(ctrl);
ctrl.MouseClick += new MouseEventHandler(ctrl_MouseClick);
}
void ctrl_MouseClick(object sender, MouseEventArgs e) {
MessageBox.Show("MouseClick");
}
}The Title, TitleColor, AutoSize and Size properties and the Controls collection are all there, which is the point. The node behaves like a container of controls, and a control is added to it the same way you would add one to a Form.
The later examples show the more important shape, where the node is created by overriding OnCreate rather than by writing a constructor, because the input and output options have to exist before the node is added to an editor:
public class MyNode : STNode {
protected override void OnCreate() {
base.OnCreate();
this.Title = "MyNode";
this.TitleColor = Color.FromArgb(200, Color.Goldenrod);
//multi-connection
this.InputOptions.Add("Single", typeof(string), true);
//single-connection
this.OutputOptions.Add("Multi", typeof(string), false);
}
}Two properties carry the data model. InputOptions and OutputOptions are collections of STNodeOption, and each option has a name and a type. The boolean argument in the Add call selects the connection mode, which is why the example names the options Single and Multi in a way that is deliberately confusing: the first call adds an input named Single with multi connection, and the second adds an output named Multi with single connection. The naming in the sample is sloppy, but the mechanism is what matters.
Two connection modes and colour coding by data type
STNodeOption has two connection modes, single-connection and multi-connection, and the README defines each.
In single connection mode, one connection point can only be connected by one connection point of the same data type at a time. In multi connection mode, one connection point can be connected by multiple connection points of the same data type at the same time.
That is a meaningful distinction for a data flow editor, because it decides whether the node is a consumer of a single stream or a fan-in point. The type constraint is the other half: connections are only allowed between options of the same data type, which means the type system of the editor is the type system of the data.
The colours follow from the types. The second example overrides OnOwnerChanged, which fires when the node is added to or removed from an editor, and the override asks the owner to assign a colour to each type:
protected override void OnOwnerChanged() {
base.OnOwnerChanged();
if (this.Owner == null) return;
this.Owner.SetTypeColor(typeof(string), Color.Yellow);
this.Owner.SetTypeColor(typeof(int), Color.DodgerBlue, true);
}The last argument is the one that catches people out. Setting a type colour replaces any colour already assigned for that type in the container, while the third argument is a flag that makes the call ignore the colour already present. The comments in the example say as much, and they note that a per option colour can be set directly instead, without going through OnOwnerChanged.
So the type colouring is a shared, per type setting owned by the editor rather than a property of the node, which is the right design as soon as two nodes of different types exist in the same graph.
Data moves through DataTransfer and TransferData, not through the graph
The data exchange section explains that the earlier example only created a connectable option point and contained no actual functionality.
The mechanism is event based and runs through the option rather than the node. An STNodeOption can bind a DataTransfer event to receive all the data coming into that option, and an STNodeOption can call TransferData with an object to deliver that data to all the options connected to it.
That is a small design with large consequences. The graph is a routing structure, and the payload never travels along the connection. Instead, the sending node hands the value to its output option, and the option dispatches it to whatever is connected. A node that wants to receive data subscribes to the event on its input option.
The benefit is that the data path is decoupled from the visual connection, so a node can be developed and tested without the editor, and the same node type can be wired differently without changing its code. The cost is that you are writing event handlers rather than calling methods across the graph, and the receiver has to cope with a payload it does not control the type of.
The README demonstrates this with a two node example. One node outputs the current system time once per second and the other receives an event and displays it. The first node holds a thread and a reference to its output option, creates the option in OnCreate, and overrides OnOwnerChanged so that the thread is started when the node is added to the editor and aborted when it is removed. That lifecycle detail is the pattern to copy: work starts and stops with ownership of the node in the graph.
Version 2.0 has no controls, and version 3.0 was still in progress
The README contains an honest note about what the current version does not have, and it is the most important thing for an evaluator to read.
In the current version, 2.0, STNodeEditor provides only the STNodeControl base class and does not provide a single usable control. The accompanying demo project contains some examples of how to define a custom control, and the author points to a series of articles on custom control development for the details, saying that in later versions he will provide some common controls. The note also says that although he wants the usage to be close to WinForm, simply treating it as WinForm is not the intent.
That is a significant limitation in practice. You can build the framework, the tree, the property grid and the connection model, but every control inside a node is yours to write, and the visual result depends entirely on your own drawing code. For a project whose pitch is that a node feels like a Form, shipping the Form-like surface without the Form-like widgets is a gap.
The version story also needs setting out. The releases are V2.0 on 2021-04-30 and V1.0 on 2021-01-21, and the README's own version 3.0 notes are dated 2022-08-30. A later entry dated 2023-04-20 explains that the author had paused, mentions that the related STJson project was needed and had also been paused, and says that JSON format support for saving STNodeEditor data would follow. The last push to the repository was on 2026-08-10.
So the honest summary is that the last tagged release is from 2021, the 3.0 work described in the README was still in progress, and the most recent activity is well after the last release. A project that needs a working node editor today should treat the NuGet package as what it is, a 2.0 release with a strong core and a missing control library.
Editorial conclusion
Adopt STNodeEditor if you are building a .NET WinForms tool whose execution flow should be visible and editable at runtime rather than hard coded, and if you want a node canvas without pulling in a large graph framework. Do not adopt it expecting a design time experience, because the README states there is no visual designer yet and that version 2.0 provides only the STNodeControl base class with no usable controls, and do not adopt it if your project has moved past .NET 3.5, since the stated environment is VisualStudio 2010 on .NET 3.5. Before you build on it, read the V3_EN.md progress notes, check which control set the version you install actually contains, and confirm the NuGet package name, ST.Library.UI, is the one your project will reference.
Frequently asked questions
What is STNodeEditor and what does it provide?
It is a node editor for .NET WinForms, drawn with GDI, with no dependency libraries and a size of just over 100 KB. It consists of three parts, a TreeView of available nodes, a PropertyGrid for node properties and the NodeEditor canvas where the user assembles the execution flow.
How do I install STNodeEditor?
The NuGet package is ST.Library.UI, and the README gives the command PM> Install-Package ST.Library.UI -Version 2.0.0. The stated build environment is VisualStudio 2010 on .NET 3.5.
What controls does the current version of STNodeEditor provide?
In version 2.0 it provides only the STNodeControl base class and no usable control at all, with the demo project showing how to define a custom control. The author notes that common controls are planned for a later version.
How does data pass between nodes in STNodeEditor?
Through the options rather than the connections. An STNodeOption binds a DataTransfer event to receive the data coming in, and calls TransferData with an object to deliver data to every option it is connected to.
What are the connection modes and the colour rules in STNodeEditor?
An STNodeOption is either single-connection, where one connection point can be joined by only one point of the same type, or multi-connection, where several can join it. Colours are assigned per data type through the owner's SetTypeColor, and the third argument controls whether an existing colour is replaced or ignored.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/debugst-stnodeeditor)Was this useful?