SimpleViewModel 0.9.7.1

There is a newer version of this package available.
See the version list below for details.

Requires NuGet 4.1.0 or higher.

dotnet add package SimpleViewModel --version 0.9.7.1
                    
NuGet\Install-Package SimpleViewModel -Version 0.9.7.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="SimpleViewModel" Version="0.9.7.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SimpleViewModel" Version="0.9.7.1" />
                    
Directory.Packages.props
<PackageReference Include="SimpleViewModel" />
                    
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 SimpleViewModel --version 0.9.7.1
                    
#r "nuget: SimpleViewModel, 0.9.7.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.
#addin nuget:?package=SimpleViewModel&version=0.9.7.1
                    
Install as a Cake Addin
#tool nuget:?package=SimpleViewModel&version=0.9.7.1
                    
Install as a Cake Tool

SimpleViewModel

A lightweight WPF ViewModel framework with automatic source generation that eliminates boilerplate code while maintaining full control over your view models.

NuGet Version NuGet Downloads License: MIT

Features

  • Zero Boilerplate Commands: Transform methods into ICommand properties with a simple [Command] attribute
  • Automatic Property Binding: Generate observable properties from fields using [Bind] attribute
  • Source Generation: All code generation happens at compile time with no runtime reflection
  • Lightweight: Minimal dependencies and overhead
  • Type Safe: Full IntelliSense support and compile-time validation
  • WPF Optimized: Built specifically for WPF applications with proper CommandManager integration

Table of Contents

Quick Start

Installation

<PackageReference Include="SimpleViewModel" Version="0.9.7" />

Basic Usage

  1. Create a ViewModel:
using SimpleViewModel;
using SimpleViewModel.BaseClasses;

[ViewModel]
public partial class MainViewModel
{
    [Command]
    public void SaveData()
    {
        // Your save logic here
        MessageBox.Show("Data saved!");
    }

    [Command] 
    public void LoadData()
    {
        // Your load logic here
        MessageBox.Show("Data loaded!");
    }
}
  1. Bind to XAML:
<Window x:Class="MyApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel>
        <Button Content="Save" Command="{Binding SaveDataCommand}" />
        <Button Content="Load" Command="{Binding LoadDataCommand}" />
    </StackPanel>
</Window>
  1. Set DataContext:
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new MainViewModel();
    }
}

That's it! The source generator automatically creates SaveDataCommand and LoadDataCommand properties for you.

Advanced Features

Observable Properties

Use the [Bind] attribute to automatically generate observable properties:

[ViewModel]
public partial class UserViewModel
{
    [Bind]
    private string _firstName = "";
    
    [Bind]
    private string _lastName = "";
    
    [Bind]
    private int _age;
}

Generated code includes proper INotifyPropertyChanged implementation:

public string FirstName
{
    get => _firstName;
    set => SetProperty(ref _firstName, value);
}

Property Change Callbacks

Add custom logic when properties change:

[ViewModel]
public partial class UserViewModel
{
    [Bind(OnChangeMethodName = nameof(OnNameChanged))]
    private string _name = "";
    
    private void OnNameChanged()
    {
        // Custom logic when name changes
        Console.WriteLine($"Name changed to: {_name}");
    }
}

Command with CanExecute

Commands can include conditional execution logic:

[ViewModel]
public partial class DocumentViewModel
{
    [Bind]
    private string _selectedItem = "";

    [Command(CanExecuteMethodName = nameof(CanDelete))]
    public void Delete()
    {
        // Delete logic here
        Console.WriteLine($"Deleting {_selectedItem}");
    }
    
    public bool CanDelete()
    {
        return !string.IsNullOrEmpty(_selectedItem);
    }
}

Command with Parameters

Commands automatically support parameters through the Execute method:

[ViewModel]
public partial class DocumentViewModel
{
    [Command]
    public void DeleteItem()
    {
        // Note: Parameter handling is done in the generated command class
        // The method itself doesn't need to accept parameters
    }
}

How It Works

SimpleViewModel uses Roslyn source generators to analyze your code at compile time and automatically generate:

  1. Partial ViewModel Class: Extends your class to inherit from BaseViewModel
  2. Command Classes: Each [Command] method gets a corresponding command class that inherits from BaseCommand
  3. Command Properties: Properties that expose the commands for data binding (lazily initialized)
  4. Observable Properties: Properties with INotifyPropertyChanged support for [Bind] fields

All generated code is available in IntelliSense and can be debugged normally.

Generated Code Example

Your Code:

[ViewModel]
public partial class MyViewModel
{
    [Command]
    public void DoSomething() => Console.WriteLine("Done!");
}

Generated ViewModel Extension:

public partial class MyViewModel : BaseViewModel
{
    private Command_DoSomething? _DoSomethingCommand { get; set; }
    public Command_DoSomething DoSomethingCommand => _DoSomethingCommand ??= new(this);
}

Generated Command Class:

public sealed class Command_DoSomething : BaseCommand
{
    private readonly MyViewModel vm;
    
    public Command_DoSomething(MyViewModel vm)
    {
        this.vm = vm;
    }
    
    public override void Execute(object? parameter)
    {
        vm.DoSomething();
    }
}

Best Practices

  1. Use Partial Classes: Always mark your view models as partial to allow source generation
  2. Apply ViewModel Attribute: Use [ViewModel] on your class - the generator automatically makes it inherit from BaseViewModel
  3. Field Naming: Use underscore prefixes for fields marked with [Bind] (e.g., _title becomes Title property)
  4. Async Commands: For async operations, use async void in command methods
  5. Parameter Validation: Commands receive parameters through the Execute(object? parameter) method in the generated class
  6. Dependency Injection: Use constructor injection for services and dependencies

Troubleshooting

Generator Not Running

If the source generator isn't creating commands:

  1. Ensure you have the [ViewModel] attribute on your class
  2. Make sure the class is marked as partial
  3. Check that methods have the [Command] attribute and are public
  4. Verify fields have the [Bind] attribute for observable properties
  5. Clean and rebuild your solution

Missing Commands in XAML

If commands aren't appearing in XAML IntelliSense:

  1. Rebuild the project to trigger source generation
  2. Check that the generated files are created (enable <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles> to see them)
  3. Ensure proper namespace imports in XAML

Common Issues

  • Fields not generating properties: Make sure fields are marked with [Bind] and are private
  • Commands not working: Ensure methods are public and marked with [Command]
  • CanExecute not working: Verify the method name in CanExecuteMethodName exists and is public with bool return type

Requirements

  • .NET 8.0 or .NET 9.0 (Windows targets only)
  • Windows (WPF applications only)
  • C# 10.0 or later

License

MIT License - see LICENSE file for details.

Contributing

Contributions are welcome! Please feel free to submit issues and pull requests.

Repository


Built with ❤️ for the WPF community

Product Compatible and additional computed target framework versions.
.NET net8.0-windows7.0 is compatible.  net9.0-windows was computed.  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.
  • net8.0-windows7.0

    • No dependencies.
  • net9.0-windows7.0

    • No dependencies.

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
0.9.7.4 42 7 days ago
0.9.7.3 44 7 days ago
0.9.7.2 44 7 days ago
0.9.7.1 132 16 days ago
0.9.7 126 17 days ago
0.9.6.4 131 17 days ago
0.9.6.3 126 17 days ago
0.9.6.2 127 17 days ago
0.9.6.1 127 17 days ago
0.9.6 129 17 days ago
0.9.5.4 124 17 days ago
0.9.5.3 124 17 days ago
0.9.5.2 126 17 days ago
0.9.5.1 129 18 days ago
0.9.5 126 18 days ago
0.9.4 129 18 days ago
0.9.3 128 18 days ago
0.9.2 130 18 days ago
0.9.1 124 18 days ago
0.9.0 126 18 days ago