能快速構建和定製網絡拓撲圖的WPF開源項目-NodeNetwork

能快速構建和定製網絡拓撲圖的WPF開源項目-NodeNetwork

在現代軟體開發中,數據可視化和可交互性越來越受到關注。為了實現這一點,通常需要使用各種圖表、表格、網絡拓撲圖等控件。NodeNetwork就是一種這樣的自定義方式,它是一個基於C# WPF的開源項目,可以幫助我們快速構建和定製網絡拓撲圖。

最後更新 2023/3/18 下午10:05
沙漠尽头的狼
預計閱讀 12 分鐘
分類
WPF
專題
WPF開源項目
標籤
.NET C# WPF WPF開源項目 開源項目

大家好,我是沙漠盡頭的狼,今天介紹一個WPF開源項目-NodeNetwork,它可以幫助我們快速建置和自訂網路拓撲圖。

一、前言

在現代軟體開發中,資料視覺化和可互動性越來越受到關注。為了實現這一點,通常需要使用各種圖表、表格、網路拓撲圖等控制項。然而,對於某些特殊的場景,這些控制項可能無法滿足需求,此時我們需要一種自訂的方式來展示和處理資料。NodeNetwork就是這樣一種自訂方式,它是一個基於C# WPF的開源專案,可以幫助我們快速建置和自訂網路拓撲圖。

NodeNetwork的程式碼託管在GitHub上,是由荷蘭的一位開發者Wouterdek所建立和維護的。在本文中,我們將對NodeNetwork進行介紹和分析,希望讀者能夠透過本文了解到NodeNetwork的核心概念、應用場景和使用方法,同時也能夠掌握一些開發NodeNetwork的技巧和經驗。

倉庫地址:https://github.com/Wouterdek/NodeNetwork

倉庫截圖:

倉庫截圖

倉庫原始碼結構:

倉庫原始碼結構

二、範例

1. 計算器範例

此範例允許使用者使用節點編輯器建立數學運算式。 修改節點時,將自動計算和更新結果值。 此應用程式包含節點驗證,自訂節點子類別,值輸入/輸出,自訂輸入編輯器,節點列表,...

下面是計算器範例應用程式的示範:

計算器範例應用程式的示範

2. 程式碼產生器範例

在此範例中,使用者可以建立 LUA 程式碼。與虛幻引擎中的藍圖類似,編輯器具有執行流程和資料流。 自訂輸入/輸出埠、節點編輯器提供了更直觀的體驗。

下面是程式碼產生器應用程式的截圖:

程式碼產生器應用程式的截圖

3. 著色器編輯器範例

此庫更實用的範例可能是著色器編輯器。

下面是使用 NodeNetwork 製作的著色器編輯器範例的示範:

著色器編輯器範例的示範

這些範例應用程式可在此處下載,其原始碼包含在儲存庫中,庫的二進位版本在 NuGet 上可用。

三、特徵

  1. 專為 .NET Framework 4.7.2 和 .NET Core 3.1 或更高版本構建。
  2. 開放、寬鬆的授權-Apache-2.0 license
  3. 使用現代反應式 MVVM 程式碼構建的互動式、可靠的控制項。
  4. 順滑的平移、縮放控制項。
  5. 自動佈局系統。
  6. 高度可自訂,但預設情況下易於使用。
  7. 強大的節點和連接驗證支援。
  8. 大量的單元測試提供支援。
  9. ...

四、NodeNetwork的核心概念

以下內容可參考倉庫元件說明頁。

1. 節點(Node)

節點是NodeNetwork中的最基本元素,可以表示任何一個資料來源或處理單元。每個節點可以包含一個或多個輸入埠和輸出埠,分別表示節點接收和輸出的資料。NodeNetwork中內建了幾種常用的節點類型,如常量節點、計算節點、輸入輸出節點等,同時也支援自訂節點類型。

2. 連接(Connection)

連接是NodeNetwork中的一個核心概念,用於表示節點之間的資料傳輸關係。每個連接都有一個來源埠和目標埠,來源埠表示資料的來源,目標埠表示資料的目標。連接還可以攜帶一些元資料(metadata),用於描述連接的一些附加資訊,如顏色、線寬等。

3. 埠(Port)

埠是節點的輸入或輸出端點,用於與其他節點進行連接。每個埠都有一個類型,表示該埠所能接收或輸出的資料類型。埠還可以有一些其他屬性,如標籤、描述等,用於描述埠的功能和作用。

4. 圖形介面(GUI)

NodeNetwork是基於WPF框架實現的,因此它具有一套強大的圖形介面(GUI)系統。在NodeNetwork中,每個節點和連接都可以顯示為一個圖形化的元素,使用者可以透過拖拽、縮放等方式對這些元素進行操作。

5. 佈局(Layout)

佈局是NodeNetwork的另一個重要概念,用於控制節點和連接的位置和大小。NodeNetwork中提供了多種不同的佈局方式,如自由佈局、柵格佈局、力導向佈局等。使用者可以根據具體的需求選擇不同的佈局方式,並且可以透過程式碼或圖形介面進行佈局的自訂和調整。

6. 序列化與反序列化(Serialization and Deserialization)

在實際的應用中,我們需要將節點和連接儲存到檔案或資料庫中,或者從檔案或資料庫中讀取節點和連接。為了實現這一點,NodeNetwork提供了序列化和反序列化功能。序列化是將節點和連接轉換成一個資料流的過程,反序列化則是將資料流轉換成節點和連接的過程。NodeNetwork支援多種不同的序列化格式,如XML、JSON、二進位等,使用者可以根據具體需求選擇不同的格式。

五、NodeNetwork的應用場景

NodeNetwork具有廣泛的應用場景,下面介紹其中的幾個:

1. 資料處理和分析

NodeNetwork可以幫助我們快速構建資料處理和分析的工具。例如,我們可以建立一個圖形化的工作流,將不同的資料處理節點連接起來,從而實現資料的前處理、轉換和分析。

2. 圖形化編輯器

NodeNetwork可以幫助我們快速構建圖形化的編輯器。例如,我們可以建立一個圖形化的介面,用於編輯和配置某些參數或選項,這些參數或選項可以透過節點和連接的方式進行互動和傳遞。

3. 視覺化和互動式展示

NodeNetwork可以幫助我們快速構建視覺化和互動式的展示工具。例如,我們可以建立一個圖形化的網路拓撲圖,用於展示某些設備或系統的連接關係和狀態。使用者可以透過節點和連接的方式進行互動和控制,例如新增、刪除、修改節點和連接等。

六、NodeNetwork的使用方法

NodeNetwork的使用方法非常簡單,下面介紹其中的幾個步驟(參考不到30行代碼的Hello world)。

首先,使用 Dotnet 8建立WPF專案,專案命名為NodeNetworkTest,您可以使用 .NET Framework 4.7.2 以上或 .NET CORE 3.x 以上,站長使用 .NET 8只是8預覽版2剛出來試試而已。

1. 安裝NodeNetwork

NodeNetwork可以透過NuGet套件管理器進行安裝。在Visual Studio中,打開「套件管理器主控台」,輸入以下命令即可安裝NodeNetwork:

Install-Package NodeNetwork

2. 註冊NodeNetwork檢視

MVVM在整個NodeNetwork庫中都在貫徹使用。有關MVVM的介紹請點選這裡查看。使用庫中的元素,您需要建立合適的檢視,並為其提供相應的ViewModel實例。

在使用庫之前,請在App.xaml.cs檔案的OnStartup方法內使用NNViewRegistrar.RegisterSplat()方法將NodeNetwork的檢視和相應的ViewModel進行註冊關聯。

using System.Windows;
using NodeNetwork;

namespace NodeNetworkTest;

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);
        NNViewRegistrar.RegisterSplat();
    }
}

3. 建立檢視

打開MainWindow.xaml,加入NodeNetwork命名空間xmlns:nodenetwork="clr-namespace:NodeNetwork.Views;assembly=NodeNetwork",並加入NetworkView檢視<nodenetwork:NetworkView x:Name="networkView" />,NetworkView表示整個網路拓撲圖:

<Window x:Class="NodeNetworkTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:nodenetwork="clr-namespace:NodeNetwork.Views;assembly=NodeNetwork"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <nodenetwork:NetworkView x:Name="networkView" />
    </Grid>
</Window>

4. 建立節點和連接

在NodeNetwork中,建立節點和連接非常簡單。首先,我們需要建立NetworkViewModel,它是NetworkView檢視的ViewModel,可以透過以下程式碼建立:

var network = new NetworkViewModel();
networkView.ViewModel = network;

然後透過以下程式碼建立第一個節點:

var node1 = new NodeViewModel();
node1.Name = "節點1";
network.Nodes.Add(node1);

並給第一個節點建立一個輸入埠:

var node1Input = new NodeInputViewModel();
node1Input.Name = "節點1輸入";
node1.Inputs.Add(node1Input);

建立第二個節點,並以同樣的方式給此節點建立一個輸出埠:

var node2 = new NodeViewModel();
node2.Name = "節點2";
network.Nodes.Add(node2);

var node2Output = new NodeOutputViewModel();
node2Output.Name = "節點2輸出";
node2.Outputs.Add(node2Output);

最後,我們可以透過以下程式碼將節點1的輸入埠和節點2的輸出埠連接到一起:

var connection = new ConnectionViewModel(network, node1Input, node2Output);
network.Connections.Add(connection);

完整程式碼如下:

using DynamicData;
using NodeNetwork.ViewModels;
using System.Windows;

namespace NodeNetworkTest;

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        // 建立NetworkView檢視的ViewModel實例
        var network = new NetworkViewModel();

        // 給檢視(networkView)賦值viewmodel(network)
        networkView.ViewModel = network;

        // 建立第一個節點ViewModel,設定它的名稱並將此節點加入到network
        var node1 = new NodeViewModel();
        node1.Name = "節點1";
        network.Nodes.Add(node1);

        // 建立第一個節點的輸入埠ViewModel,設定它的名稱並加入第一個節點
        var node1Input = new NodeInputViewModel();
        node1Input.Name = "節點1輸入";
        node1.Inputs.Add(node1Input);

        // 建立第二個節點ViewModel,設定它的名稱並將此節點加入到network,並以同樣的方式給此節點新增一個輸出Create the second node viewmodel, set its name, add it to the network and add an output in a similar fashion.
        var node2 = new NodeViewModel();
        node2.Name = "節點2";
        network.Nodes.Add(node2);

        var node2Output = new NodeOutputViewModel();
        node2Output.Name = "節點2輸出";
        node2.Outputs.Add(node2Output);

        // 將節點1的輸入埠和節點2的輸出埠連接到一起
        var connection = new ConnectionViewModel(network, node1Input, node2Output);
        network.Connections.Add(connection);
    }
}

執行程式看效果:

範例程式碼已經全部給了,你也可以戳這複製。

5. 佈局

在NodeNetwork中,佈局非常靈活和自由。我們可以透過程式碼或圖形介面進行佈局。例如,我們可以透過以下程式碼將節點放置在指定的位置:

node.Position = new Point(100, 100);

透過以下程式碼調整整個網路拓撲圖的佈局(參考佈局文件):

ForceDirectedLayouter layouter = new ForceDirectedLayouter();
var config = new Configuration
{
    Network = yourNetwork,
};
layouter.Layout(config, 10000);

6. 序列化與反序列化

在NodeNetwork中,序列化和反序列化非常簡單。我們可以透過以下程式碼將節點和連接序列化為XML格式:

var serializer = new XmlSerializer(typeof(NodeNetworkViewModel));
var writer = new StringWriter();
serializer.Serialize(writer, nodeNetwork);

然後,我們可以將XML字串儲存到檔案或資料庫中。反序列化也非常簡單。我們可以透過以下程式碼從XML字串中反序列化節點和連接:

var serializer = new XmlSerializer(typeof(NodeNetworkViewModel));
var reader = new StringReader(xmlString);
var nodeNetwork = (NodeNetworkViewModel)serializer.Deserialize(reader);

七、總結

NodeNetwork是一個非常實用和靈活的C# WPF開源專案,它可以幫助我們快速建構圖形化的網路拓撲圖,實現節點和連接的互動和傳遞。NodeNetwork提供了豐富的功能和特性,例如節點和連接的自訂、佈局和調整、序列化與反序列化等,可以滿足各種不同的應用需求。NodeNetwork的應用場景非常廣泛,例如資料處理和分析、圖形化編輯器、視覺化和互動式展示等。NodeNetwork的使用方法非常簡單,我們只需要安裝NodeNetwork、建立節點和連接、佈局和調整、序列化與反序列化即可。

  • 入門指南

有關使用此庫的簡單快速入門指南,請參閱此頁面上的說明書章節。 該文件包括設定資訊、說明書章節、範例和 API 參考。

  • 授權

該庫在 Apache 許可證 2.0 下獲得許可。(見 choosealicense.com/licenses/apache-2.0 簡要介紹)此許可證的副本包含在 LICENSE 下的儲存庫中。

  • 文件

文件可在此處獲得。如果要對文件進行更改,可以透過向 gh-pages 分支發出拉取請求來實現。

  • 貢獻

這些操作在 GitHub 頁面上非常受歡迎:錯誤回報、修補程式、功能請求、拉取請求...

  • 微信技術交流群:新增微信(codewf)備註「入群」
  • QQ技術交流群:771992300。
繼續探索

延伸閱讀

更多文章
同分類 / 同標籤 2025/1/26

WPF 藉助自訂 XML 檔案實現國際化

本文詳細介紹了在WPF程式中使用自訂XML檔案實現國際化的方法,包括安裝必備NuGet套件、動態獲取語言清單、動態切換語言、在程式碼和XAML介面中使用翻譯字串等內容,同時提供了原始碼連結,幫助開發者輕鬆實現WPF應用程式的國際化。

繼續閱讀