DEV Community

Cover image for DevLog 20250531: Some Problems We've Had with Nodify (and Some Tricks)
1

DevLog 20250531: Some Problems We've Had with Nodify (and Some Tricks)

The Windows version of Divooka node graph editor is using Nodify for node graph drawing. We've had mixed experience - on the one hand it's great productivity boost not having to implement a node based graph editor ourselves, on the other hand every version upgrade is pain yet necessary since new features are desirable.

Overall Verdict

The documentation for the library is pretty good - though one need to combine both the wiki and the examples to fully understand what's going on.

Also the MVVM pattern is a pain as always (e.g. duplicate definition of same things on view and model to keep data binding happy), despite occasional "wonder" moments when things just work.

Pain Points

Below is how background is drawn per example. Worked in Version 5. Stopped working in version 7.

<DrawingBrush x:Key="SmallGridLinesDrawingBrush"
      TileMode="Tile"
      ViewportUnits="Absolute"
      Viewport="0 0 15 15"
      Transform="{Binding ViewportTransform, ElementName=Editor}"
      Drawing="{StaticResource SmallGridGeometry}" />

<DrawingBrush x:Key="LargeGridLinesDrawingBrush"
      TileMode="Tile"
      ViewportUnits="Absolute"
      Opacity="0.5"
      Viewport="0 0 150 150"
      Transform="{Binding ViewportTransform, ElementName=Editor}"
      Drawing="{StaticResource LargeGridGeometry}" />
Enter fullscreen mode Exit fullscreen mode

In version 7, nodify:GraphEditor's RightMouseButtonUp event is not fired (during first click) due to panning logic.

In version 7, BaseConnection has IsSelected property but that cannot be bound.

When a pop-up is closed and editor is re-activated, it looks like the editor is going to attempt to area select everything from top left corner. Not sure whether this is a Nodify issue or how we handled window activation/deactivation.

Image description

Some Remarks

Notice the KnotNode is a traditional construct and may sound like a good idea at first glance (and is used in Unreal Blueprint so it's popular), but actually makes both GUI and backend implementation unnecessary complicated.

Tricks

In version 7, BaseConnection now expose IsSelected dependency property, which may allow interesting behavior in style trigger:

<Style x:Key="ConnectionStyle" TargetType="{x:Type nodify:BaseConnection}">
    <!-- default appearance -->
    <Setter Property="Stroke" Value="Black"/>
    <Setter Property="Cursor" Value="Hand"/>
    <Setter Property="ToolTip" Value="Double click to split"/>

    <Style.Triggers>
        <!-- trigger on the IsSelected attached‐property -->
        <Trigger Property="nodify:BaseConnection.IsSelected" Value="True">
            <!-- when selected, override the Stroke color -->
            <Setter Property="Stroke" Value="Red"/>
        </Trigger>
    </Style.Triggers>
</Style>
Enter fullscreen mode Exit fullscreen mode

In practice, the SelectionChanged event and SelectedConnections dependency property on NodifyEditor is very hard to deal with right now. For the purpose of implementing a "connection highlight" effect, don't bother with "selection". Instead, a single data trigger suffice. In this case, we don't even need Nodify v7's IsSelected/IsSelectable (must be true for connections to be selected) property on BaseConnection.

<Style x:Key="ConnectionStyle" TargetType="{x:Type nodify:BaseConnection}">
    <Style.Triggers>
        <DataTrigger Binding="{Binding IsHighlighted}" Value="True">
            <Setter Property="Stroke" Value="Red"/>
        </DataTrigger>
    </Style.Triggers>
</Style>
Enter fullscreen mode Exit fullscreen mode

References

DevCycle image

Ship Faster, Stay Flexible.

DevCycle is the first feature flag platform with OpenFeature built-in to every open source SDK, designed to help developers ship faster while avoiding vendor-lock in.

Start shipping

Top comments (0)

Tiger Data image

🐯 🚀 Timescale is now TigerData: Building the Modern PostgreSQL for the Analytical and Agentic Era

We’ve quietly evolved from a time-series database into the modern PostgreSQL for today’s and tomorrow’s computing, built for performance, scale, and the agentic future.

So we’re changing our name: from Timescale to TigerData. Not to change who we are, but to reflect who we’ve become. TigerData is bold, fast, and built to power the next era of software.

Read more

👋 Kindness is contagious

Discover more in this insightful article and become part of the thriving DEV Community. Developers at every level are welcome to share and enrich our collective expertise.

A simple “thank you” can brighten someone’s day. Please leave your appreciation in the comments!

On DEV, sharing skills lights our way and strengthens our connections. Loved the read? A quick note of thanks to the author makes a real difference.

Count me in