CoreOne.Winforms 1.1.0.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package CoreOne.Winforms --version 1.1.0.1
                    
NuGet\Install-Package CoreOne.Winforms -Version 1.1.0.1
                    
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="CoreOne.Winforms" Version="1.1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CoreOne.Winforms" Version="1.1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="CoreOne.Winforms" />
                    
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 CoreOne.Winforms --version 1.1.0.1
                    
#r "nuget: CoreOne.Winforms, 1.1.0.1"
                    
#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 CoreOne.Winforms@1.1.0.1
                    
#: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=CoreOne.Winforms&version=1.1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=CoreOne.Winforms&version=1.1.0.1
                    
Install as a Cake Tool

CoreOne.Winforms

A modern, feature-rich WinForms library that provides dynamic model-based form generation with automatic two-way data binding, themed controls, and smooth animations. Built for .NET 9.0 with dependency injection support.

NuGet License: MIT

🚀 Features

Dynamic Form Generation

  • ModelControl - Automatically generates form fields from your model properties
  • Two-way data binding - Changes in controls update the model, and vice versa
  • Reactive updates - Built on reactive patterns with Subject<T> for change notifications
  • Dirty tracking - Know when data has been modified

Smart Grid Layout

  • 6-column Bootstrap-style grid - Responsive layout system
  • [GridColumn] attribute - Control field width (1-6 columns)
  • Auto-sizing - Calculates ideal form dimensions
  • Labels above controls - Clean, modern layout
  • Type-based dropdown sources - [DropdownSource<T>] attribute
  • Dependency tracking - [DropdownDependsOn] for cascading dropdowns
  • Sync & Async providers - Support for both data retrieval patterns
  • Auto-refresh - Dependent dropdowns update automatically

Themed Controls

  • OButton - Modern button with hover/press states
  • AnimatedPanel - Smooth transitions and animations
  • LoadingCircle - Loading indicator control
  • BaseView - Base control for creating custom views

Additional Features

  • Validation support - Extensible validation framework
  • Custom attributes - [Ignore], [Visible], and more
  • Dependency injection - First-class DI support
  • SOLID architecture - Clean, maintainable codebase

📦 Installation

Install via NuGet Package Manager:

dotnet add package CoreOne.Winforms

Or via Package Manager Console:

Install-Package CoreOne.Winforms

🎯 Quick Start

1. Define Your Model

using CoreOne.Winforms.Attributes;

public class Customer
{
    [GridColumn(GridColumnSpan.Half)]  // Takes 3 columns (half of 6)
    public string FirstName { get; set; }
    
    [GridColumn(GridColumnSpan.Half)]
    public string LastName { get; set; }
    
    [GridColumn(GridColumnSpan.Full)]  // Takes all 6 columns
    public string Email { get; set; }
    
    [DropdownSource<CountryProvider>]
    [GridColumn(GridColumnSpan.Half)]
    public string Country { get; set; }
    
    [DropdownSource<StateProvider>]
    [DropdownDependsOn(nameof(Country))]  // Refreshes when Country changes
    [GridColumn(GridColumnSpan.Half)]
    public string State { get; set; }
    
    public DateTime BirthDate { get; set; }
    
    public bool IsActive { get; set; }
    
    [Ignore]  // Won't generate a control
    public int InternalId { get; set; }
}

2. Setup Dependency Injection

using CoreOne.Winforms.Extensions;
using Microsoft.Extensions.DependencyInjection;

var services = new ServiceCollection();

// Register CoreOne.Winforms services
services.AddFormServices();

// Register your dropdown providers
services.AddSingleton<CountryProvider>();
services.AddSingleton<StateProvider>();

var serviceProvider = services.BuildServiceProvider();

3. Create and Use ModelControl

using CoreOne.Winforms.Controls;

public class MyForm : Form
{
    private readonly ModelControl _modelControl;
    
    public MyForm(IServiceProvider services)
    {
        var modelBinder = services.GetRequiredService<IModelBinder>();
        _modelControl = new ModelControl(services, modelBinder);
        _modelControl.Dock = DockStyle.Fill;
        
        // Handle save button click
        _modelControl.SaveClicked += OnSaveClicked;
        
        Controls.Add(_modelControl);
        
        // Bind your model
        var customer = new Customer 
        { 
            FirstName = "John", 
            LastName = "Doe" 
        };
        _modelControl.SetModel(customer);
    }
    
    private void OnSaveClicked(object? sender, ModelSavedEventArgs e)
    {
        if (e.IsModified)
        {
            // Get the updated model
            var customer = _modelControl.GetModel<Customer>();
            
            // Save to database...
            MessageBox.Show($"Saved: {customer?.FirstName} {customer?.LastName}");
            
            _modelControl.AcceptChanges();  // Clear dirty flag
        }
    }
}

📚 Advanced Usage

Creating Custom Dropdown Providers

using CoreOne.Winforms;
using CoreOne.Winforms.Models;

public class CountryProvider : IDropdownSourceProviderSync
{
    private IDropdownContext? _context;
    
    public void Initialize(IDropdownContext context)
    {
        _context = context;
        // Subscribe to changes, setup refresh logic, etc.
    }
    
    public IEnumerable<DropdownItem> GetItems(object model)
    {
        // Fetch from database, API, etc.
        return new[]
        {
            new DropdownItem("United States", "US"),
            new DropdownItem("Canada", "CA"),
            new DropdownItem("Mexico", "MX")
        };
    }
    
    public void Dispose()
    {
        // Cleanup resources
    }
}

public class StateProvider : IDropdownSourceProviderSync
{
    public void Initialize(IDropdownContext context) { }
    
    public IEnumerable<DropdownItem> GetItems(object model)
    {
        // Access the model to get dependent property value
        var customer = (Customer)model;
        
        return customer.Country switch
        {
            "US" => new[] 
            { 
                new DropdownItem("California", "CA"),
                new DropdownItem("Texas", "TX"),
                new DropdownItem("New York", "NY")
            },
            "CA" => new[] 
            { 
                new DropdownItem("Ontario", "ON"),
                new DropdownItem("British Columbia", "BC")
            },
            _ => Array.Empty<DropdownItem>()
        };
    }
    
    public void Dispose() { }
}

Async Dropdown Provider

public class ProductCategoriesProvider : IDropdownSourceProviderAsync
{
    private readonly HttpClient _httpClient;
    
    public ProductCategoriesProvider(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }
    
    public void Initialize(IDropdownContext context) { }
    
    public async Task<IEnumerable<DropdownItem>> GetItemsAsync(object model)
    {
        var response = await _httpClient.GetFromJsonAsync<Category[]>("/api/categories");
        return response?.Select(c => new DropdownItem(c.Id.ToString(), c.Name)) 
               ?? Array.Empty<DropdownItem>();
    }
    
    public void Dispose() 
    {
        _httpClient?.Dispose();
    }
}

Monitoring Property Changes

var token = SToken.Create();

_modelControl.PropertyChanged?.Subscribe(change =>
{
    Console.WriteLine($"Property '{change.PropertyName}' changed from " +
                     $"'{change.OldValue}' to '{change.NewValue}'");
}, token);

// Later, dispose the token to unsubscribe
token.Dispose();

Available Attributes

Attribute Purpose Example
[GridColumn(GridColumnSpan)] Control column span (1-6) [GridColumn(GridColumnSpan.Full)]
[DropdownSource<T>] Specify dropdown provider [DropdownSource<CountryProvider>]
[DropdownDependsOn("PropertyName")] Declare dropdown dependency [DropdownDependsOn(nameof(Country))]
[Ignore] Skip property in form generation [Ignore]
[Visible(bool)] Control visibility [Visible(false)]

Grid Column Spans

public enum GridColumnSpan
{
    None = 0,
    One = 1,         // 1/6 width
    Two = 2,         // 1/3 width
    Three = 3,       // 1/2 width (Half width)
    Four = 4,        // 2/3 width
    Five = 5,        // 5/6 width
    Six = 6,         // Full width
    Default = Six    // Default is full width (6 columns)
}

🎨 Themed Controls

OButton - Modern Button Control

var button = new OButton
{
    Text = "Click Me",
    BackColor = Color.FromArgb(0, 120, 215),
    ForeColor = Color.White,
    Width = 120,
    Height = 35
};

AnimatedPanel - Transitions & Animations

var panel = new AnimatedPanel();
// Built-in transition support for smooth animations

LoadingCircle

var loading = new LoadingCircle
{
    Active = true,
    Color = Color.Blue
};

🏗️ Architecture

CoreOne.Winforms follows SOLID principles with a clean, testable architecture:

  • Services - IModelBinder, IPropertyControlFactory, IDropdownRefreshManager
  • Factory Pattern - Composite factory for control creation
  • Dependency Injection - Constructor injection throughout
  • Reactive Programming - Observable property changes
  • Repository Pattern - Ready for your data layer

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

📝 Requirements

  • .NET 9.0 or later
  • Windows OS (WinForms)
  • Visual Studio 2022 or later (recommended)

Made with ❤️ by Juan Lopez

Product Compatible and additional computed target framework versions.
.NET net9.0-windows7.0 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.3.2.1 96 3/4/2026
1.3.2 87 2/25/2026
1.3.1 98 2/4/2026
1.3.0 89 2/4/2026
1.2.0 97 2/2/2026
1.1.0.1 98 1/29/2026
1.1.0 97 1/29/2026
1.0.1.1 178 7/10/2025
1.0.1 180 7/8/2025
1.0.0 187 7/8/2025