OpenXingsCore 1.1.0

dotnet add package OpenXingsCore --version 1.1.0
                    
NuGet\Install-Package OpenXingsCore -Version 1.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="OpenXingsCore" Version="1.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="OpenXingsCore" Version="1.1.0" />
                    
Directory.Packages.props
<PackageReference Include="OpenXingsCore" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add OpenXingsCore --version 1.1.0
                    
#r "nuget: OpenXingsCore, 1.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package OpenXingsCore@1.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=OpenXingsCore&version=1.1.0
                    
Install as a Cake Addin
#tool nuget:?package=OpenXingsCore&version=1.1.0
                    
Install as a Cake Tool

OpenXingsCore

A WPF-based .NET framework for industrial monitoring and control applications.
OpenXingsCore provides a structured architecture for building scalable desktop applications with hierarchical data models, event-driven communication, command execution, and a rich set of dashboard UI components.


Table of Contents


Overview

OpenXingsCore is designed for industrial automation, manufacturing monitoring, and control systems. It offers:

  • Path-based data model registration via ModelHub and ModelRegistry
  • Global event bus for reactive data propagation across the application
  • Global command bus (CQRS-style) for action requests and execution
  • Task-based logic with declarative TaskBuilder for state-driven behavior
  • Handler system for managing execution contexts and task queues
  • Dashboard UI with zoomable canvas, chart controls, and extensible templates

The OpenXingsAppTest project is a sample application demonstrating framework usage, including custom ModelHubs, ViewModels, and Command executors.


Requirements

Requirement Version
.NET 9.0
Target OS Windows 10.0.26100.0 or later
UI WPF

Architecture

High-Level Architecture

┌─────────────────────────────────────────────────────────────────┐
│                     Application Layer                            │
│  (OpenXingsAppTest: MyAppComposer, ViewModels, Views)            │
└───────────────────────────┬─────────────────────────────────────┘
                            │
┌───────────────────────────▼─────────────────────────────────────┐
│                     OpenXingsCore                           │
├──────────────┬──────────────┬──────────────┬────────────────────┤
│  Models      │  Commands    │  Handlers    │  ViewModels/Views   │
│  ModelHub    │  GlobalCmdBus│  HandlerDefault│  Dashboard        │
│  ModelValue   │              │  TaskDefault  │  Controls          │
│  ModelRegistry│             │  TaskBuilder  │  Templates         │
│  GlobalEventBus│            │              │                    │
└──────────────┴──────────────┴──────────────┴────────────────────┘

Data Flow

  1. Model Registration: ModelHub registers ModelValue<T> instances with ModelRegistry and GlobalEventBus.
  2. Value Changes: When ModelValue.Value changes, GlobalEventBus publishes EventArgsModelValueChanged.
  3. Subscribers: ViewModels, Handlers, and other components subscribe to model addresses and react to changes.
  4. Commands: GlobalCommandBus routes ActionRequest objects to registered IExecutor implementations.
  5. Tasks: HandlerDefault evaluates TaskDefault conditions and executes expressions that read/write model values.

Project Structure

OpenXingsCore/
├── OpenXingsCore/     # Core framework library
│   ├── Models/             # ModelHub, ModelValue, ModelRegistry, GlobalEventBus
│   ├── Commands/           # GlobalCommandBus
│   ├── Handlers/           # HandlerDefault, TaskBuilder, TaskDefault
│   ├── ViewModels/         # Dashboard ViewModels and Controls
│   └── Views/              # WPF controls, pages, templates
│
├── OpenXingsCore/              # Core framework library
│   ├── Args/                        # EventArgs, ModelKey, RefArgsModelValue
│   ├── Commands/                    # GlobalCommandBus, CommandResult, ActionCommand
│   ├── Constants.cs                 # Message priorities, config paths
│   ├── Converters/                  # Value converters for WPF
│   ├── Datas/                       # HandlerContext, SettingDefault
│   ├── Handlers/                    # HandlerDefault, HandlerHub
│   ├── Models/                      # Data model layer
│   │   ├── ModelHub.cs              # Container for ModelValue registration
│   │   ├── ModelValue.cs             # Typed observable value holder
│   │   ├── ModelRegistry.cs         # Global model lookup by PathKey + model name
│   │   ├── ModelAddress.cs          # Path:ModelName address
│   │   ├── GlobalEventBus.cs        # Pub/sub for model value changes
│   │   ├── PathKey.cs               # Hierarchical path identifier
│   │   └── Logistics/               # LogiModelPort, LogiModelStage, LogiModelLane
│   ├── Tasks/                       # Task execution
│   │   ├── TaskBuilder.cs           # Fluent API for TaskDefault
│   │   ├── TaskDefault.cs           # State, condition, action, timeout
│   │   ├── ExpressionBuilder.cs     # Model key binding for expressions
│   │   └── SeriesTaskDefault.cs     # Sequential task execution
│   ├── States/                      # State definitions
│   ├── Utils/                       # ExpressionEvaluator, ModelResolver
│   ├── UtilityInterface/            # IExecutor, IModelValue, ISubscribe, etc.
│   ├── ViewModels/                  # MVVM ViewModels
│   │   ├── Controls/                # ViewModelButton, ViewModelInfo, ViewModelChart*, etc.
│   │   ├── Logistics/               # ViewModelPort, ViewModelStage, ViewModelLane
│   │   ├── Pages/                   # ViewModelDashboard, ViewModelSystemMonitor
│   │   ├── Handlers/                # ViewModelHandler
│   │   └── Dashboard/               # DashboardColumnBuilder, DashboardItemFactory
│   ├── Views/                       # WPF controls and pages
│   │   ├── Controls/                # ControlButton, ControlChart*, ControlPort, etc.
│   │   ├── Pages/                   # PageDashboard, PageSystemMonitor, PageSettings
│   │   └── Templates/               # ControlTemplates.xaml, DialogTemplates.xaml
│   ├── Styles/                      # BaseStyles, Generic.xaml
│   └── Themes/                      # DarkPropertyGridStyle
│
├── OpenXingsCore.Tests/        # Unit tests (xUnit)
│   ├── PathKeyTests.cs
│   ├── ModelRegistryTests.cs
│   ├── TaskBuilderTests.cs
│   └── GlobalCommandBusTests.cs
│
└── OpenXingsAppTest/                # Sample application
    ├── App.xaml, App.xaml.cs        # DI, logging, resource dictionaries
    ├── MainWindow.xaml              # FluentWindow with NavigationView
    ├── MyAppComposer.cs             # AppComposer implementation (HandlerContexts, Executors)
    ├── MyConstant.cs                # App-specific constants
    ├── Assets/                      # Icons, images
    ├── Commands/                    # TestActionRequest
    ├── HandlerContexts/             # HandlerContextMotor (TaskBuilder, WaitingTasks)
    ├── Datas/                       # SettingData
    ├── Executors/                   # TestExecutor (IExecutor<TestActionRequest, bool>)
    ├── ModelHubs/                   # MHubPort, MHubCarStatus, MHubMachineInfo, etc.
    ├── Models/                      # ModelFuelGauge, ModelTemperature, etc.
    ├── Services/                    # ApplicationHostService
    ├── States/                      # StateHub
    ├── ViewModels/
    │   ├── Controls/                # ViewModelPort (custom)
    │   └── Pages/                   # ViewModelDashBoardV2, ViewModelMyWindow
    └── Views/
        ├── Controls/                # ControlPort, ModuleInitialize
        ├── Pages/                   # MyMainPage
        └── Templates/               # CustomTemplates.xaml (ViewModelPort → ControlPort)

Core Components

1. ModelHub & ModelRegistry

ModelHub groups related ModelValue instances under a PathKey. Registration publishes models to ModelRegistry and GlobalEventBus.

public class MHubPort : ModelHub
{
    public MHubPort(PathKey path) : base(path)
    {
        var name = new ModelValue<string>(Keys.Name, "Default");
        Register(name);
        // ModelRegistry and GlobalEventBus are updated automatically
    }
}

ModelRegistry provides global lookup by path and model name:

if (ModelRegistry.TryGet<ModelValue<double>>(path, "TEMPERATURE", out var model))
    model.Value = 25.0;

2. GlobalEventBus

Publish/subscribe for model value changes. Subscribers receive EventArgsModelValueChanged with ModelValue, OldValue, and NewValue.

GlobalEventBus.Instance.Subscribe(model.Address, (sender, arg) =>
{
    Console.WriteLine($"{arg.ModelValue.Name}: {arg.OldValue} → {arg.NewValue}");
});

3. GlobalCommandBus

CQRS-style command dispatch. Register executors, then send commands.

// Register executor
GlobalCommandBus.Instance.Register<TestActionRequest, bool>(new TestExecutor(), "test");

// Send command
var result = GlobalCommandBus.Instance.Send<TestActionRequest, bool>(
    new TestActionRequest("Hello"));

Supports IExecutor<TCommand, TResult> and IAsyncExecutor<TCommand, TResult>.

4. TaskBuilder & TaskDefault

Declarative task definition with conditions, actions, timeouts, and priority.

var task = TaskBuilder
    .On(StateHub.StopNotReady)
    .Priority(ENUM_MSG_PRIORITY.NORMAL)
    .When("P1 > 100")
        .WithKeys((pathKey, modelKey))   // 또는 .WithModels(modelInfo1, modelInfo2)
    .Do("P2 = P1")
        .WithKeys((pathKey, key1), (pathKey, key2))
    .OnTimeout(3000, "P1 = 0")
        .WithKeys((pathKey, modelKey))
    .Build();

handlerContext.AddWaitingTask(task);

5. AppComposer

Root composition: HandlerContexts, Handlers, model registration, Executors. Manages start/stop lifecycle and JSON serialization. 조합 순서: 1) 모델 등록, 2) HandlerContext 추가, 3) Executor 등록.

public class MyAppComposer : AppComposer
{
    public MyAppComposer(SettingData setting) : base(setting)
    {
        _modelLayer.RegisterAll();
        AddHandlerContext(_modelLayer.GetHandlerContexts());  // HandlerContextMotor 등
        RegisterExecutors();
        // Handlers are created from HandlerContexts on Start()
    }
}

6. HandlerDefault

Executes TaskDefault instances from HandlerContext.WaitingTasks in a loop. Evaluates conditions, runs expressions/commands/delegates, and notifies state changes via HandlerHub.

7. Dashboard & ViewModels

  • ViewModelDashboard: ItemsTop, ItemsBottom, ItemsRight, ItemsCanvas (ObservableCollections of ViewModelCanvasItem).
  • PageDashboard: Uses VirtualizingCanvas, FastZoomBorder, and pan/zoom. Items are placed by X/Y.
  • DataTemplates: ControlTemplates.xaml maps ViewModels to controls. Applications can override via CustomTemplates.xaml.

Built-in ViewModels: ViewModelButton, ViewModelInfo, ViewModelStatus, ViewModelEdit, ViewModelChartAngular, ViewModelChartBar, ViewModelChartTrace, ViewModelColor, ViewModelImage, ViewModelPort, ViewModelStage, ViewModelLane, ViewModelHandler, ViewModelArrow, ViewModelHubGroupBorder, ViewModelGroupStack, ViewModelGroupGrid.


Getting Started

Build

dotnet build OpenXingsCore.sln

Run Sample Application

dotnet run --project OpenXingsAppTest

Create a New Application

  1. Add a project reference to OpenXingsCore.
  2. Implement AppComposer (or inherit from it): register models, AddHandlerContext(HandlerContext list), and register Executors.
  3. Register PageDashboard and ViewModelDashboard (or custom) with your navigation/DI.
  4. Define ModelHubs with PathKey and ModelValue<T> registration; define HandlerContexts that add tasks (e.g. via TaskRepository) to WaitingTasks.
  5. Optionally add CustomTemplates.xaml to override or extend DataTemplates for your ViewModels.

Run unit tests

dotnet test OpenXingsCore.Tests

Usage Examples

Custom ModelHub

public class MHubPort : ModelHub
{
    public static class Keys
    {
        public static readonly ModelKey<ModelValue<string>> Name = new("NAME");
        public static readonly ModelKey<ModelValue<int>> NumOfPass = new("NUM_OF_PASS");
    }

    public MHubPort(PathKey path) : base(path)
    {
        Register(new ModelValue<string>(Keys.Name, "Port_1"));
        Register(new ModelValue<int>(Keys.NumOfPass, 0));
    }
}

Custom ViewModel and Control

  1. Create ViewModel extending ViewModelHubDefault or ViewModelCanvasItem.
  2. Create UserControl (e.g., ControlPort.xaml).
  3. In CustomTemplates.xaml:
<DataTemplate DataType="{x:Type viewmodel:ViewModelPort}">
    <local:ControlPort/>
</DataTemplate>
  1. Merge CustomTemplates.xaml in App.xaml:
<ResourceDictionary Source="/YourApp;component/Views/Templates/CustomTemplates.xaml"/>

Sending Commands from UI

vm.HandlerButtonClick += (sender, modelInfo) =>
{
    var request = new TestActionRequest("Button 0");
    var result = GlobalCommandBus.Instance.Send<TestActionRequest, bool>(request);
};

Dependencies

Package Purpose
CommunityToolkit.Mvvm MVVM, ObservableObject, RelayCommand
LiveChartsCore.SkiaSharpView.WPF Charts and gauges
Microsoft.Extensions.Hosting Dependency injection, logging
Serilog Structured logging
Newtonsoft.Json JSON serialization
Wpf.Controls.PanAndZoom Canvas zoom/pan
SharpVectors.Wpf SVG rendering
Microsoft.Xaml.Behaviors.Wpf XAML behaviors
Wpf.Ui Fluent-style UI (referenced via DLL)

License

This project is licensed under the MIT License.

MIT License

Copyright (c) 2026 OpenXings

See the LICENSE file for the full text.

Product Compatible and additional computed target framework versions.
.NET net9.0-windows10.0.26100 is compatible.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.0 41 8/28/2026
1.0.0 93 8/20/2026