1- # SimpleViewModel
1+ # SimpleViewModel
22
33A lightweight WPF ViewModel framework with automatic source generation that eliminates boilerplate code while maintaining full control over your view models.
44
5+ [ ![ NuGet Version] ( https://img.shields.io/nuget/v/SimpleViewModel )] ( https://www.nuget.org/packages/SimpleViewModel/ )
6+ [ ![ NuGet Downloads] ( https://img.shields.io/nuget/dt/SimpleViewModel )] ( https://www.nuget.org/packages/SimpleViewModel/ )
7+ [ ![ License: MIT] ( https://img.shields.io/badge/License-MIT-yellow.svg )] ( https://opensource.org/licenses/MIT )
8+
59## Features
610
711- ** Zero Boilerplate Commands** : Transform methods into ICommand properties with a simple ` [Command] ` attribute
@@ -11,12 +15,23 @@ A lightweight WPF ViewModel framework with automatic source generation that elim
1115- ** Type Safe** : Full IntelliSense support and compile-time validation
1216- ** WPF Optimized** : Built specifically for WPF applications with proper CommandManager integration
1317
18+ ## Table of Contents
19+
20+ - [ Quick Start] ( #quick-start )
21+ - [ Advanced Features] ( #advanced-features )
22+ - [ How It Works] ( #how-it-works )
23+ - [ Generated Code Example] ( #generated-code-example )
24+ - [ Best Practices] ( #best-practices )
25+ - [ Troubleshooting] ( #troubleshooting )
26+ - [ Requirements] ( #requirements )
27+ - [ Contributing] ( #contributing )
28+
1429## Quick Start
1530
1631### Installation
1732
1833``` xml
19- <PackageReference Include =" SimpleViewModel" Version =" 0.9.6" />
34+ <PackageReference Include =" SimpleViewModel" Version =" 0.9.6.4 " />
2035```
2136
2237### Basic Usage
@@ -28,7 +43,7 @@ using SimpleViewModel;
2843using SimpleViewModel .BaseClasses ;
2944
3045[ViewModel ]
31- public partial class MainViewModel : BaseViewModel
46+ public partial class MainViewModel
3247{
3348 [Command ]
3449 public void SaveData ()
@@ -82,7 +97,7 @@ Use the `[Bind]` attribute to automatically generate observable properties:
8297
8398``` csharp
8499[ViewModel ]
85- public partial class UserViewModel : BaseViewModel
100+ public partial class UserViewModel
86101{
87102 [Bind ]
88103 private string _firstName = " " ;
@@ -105,46 +120,63 @@ public string FirstName
105120}
106121```
107122
108- ### Command with Parameters
123+ ### Property Change Callbacks
109124
110- Commands automatically support parameters :
125+ Add custom logic when properties change :
111126
112127``` csharp
113128[ViewModel ]
114- public partial class DocumentViewModel : BaseViewModel
129+ public partial class UserViewModel
115130{
116- [Command ]
117- public void DeleteItem (object parameter )
131+ [Bind (OnChangeMethodName = nameof (OnNameChanged ))]
132+ private string _name = " " ;
133+
134+ private void OnNameChanged ()
118135 {
119- if (parameter is string itemId )
120- {
121- // Delete logic here
122- }
136+ // Custom logic when name changes
137+ Console .WriteLine ($" Name changed to: {_name }" );
123138 }
124139}
125140```
126141
127- ### Integration with Dependency Injection
142+ ### Command with CanExecute
128143
129- SimpleViewModel works seamlessly with dependency injection containers :
144+ Commands can include conditional execution logic :
130145
131146``` csharp
132- // Using SimpleInjection (companion package)
133- [Singleton ][ViewModel ]
134- public partial class MainViewModel : BaseViewModel
147+ [ViewModel ]
148+ public partial class DocumentViewModel
135149{
136- private readonly IDataService _dataService ;
137-
138- public MainViewModel (IDataService dataService )
150+ [Bind ]
151+ private string _selectedItem = " " ;
152+
153+ [Command (CanExecuteMethodName = nameof (CanDelete ))]
154+ public void Delete ()
139155 {
140- _dataService = dataService ;
156+ // Delete logic here
157+ Console .WriteLine ($" Deleting {_selectedItem }" );
141158 }
142159
160+ public bool CanDelete ()
161+ {
162+ return ! string .IsNullOrEmpty (_selectedItem );
163+ }
164+ }
165+ ```
166+
167+ ### Command with Parameters
168+
169+ Commands automatically support parameters through the Execute method:
170+
171+ ``` csharp
172+ [ViewModel ]
173+ public partial class DocumentViewModel
174+ {
143175 [Command ]
144- public async void LoadData ()
176+ public void DeleteItem ()
145177 {
146- var data = await _dataService . GetDataAsync ();
147- // Handle data
178+ // Note: Parameter handling is done in the generated command class
179+ // The method itself doesn't need to accept parameters
148180 }
149181}
150182```
@@ -153,9 +185,10 @@ public partial class MainViewModel : BaseViewModel
153185
154186SimpleViewModel uses Roslyn source generators to analyze your code at compile time and automatically generate:
155187
156- 1 . ** Command Classes** : Each ` [Command] ` method gets a corresponding ` ICommand ` implementation
157- 2 . ** Command Properties** : Properties that expose the commands for data binding
158- 3 . ** Observable Properties** : Properties with ` INotifyPropertyChanged ` support for ` [Bind] ` fields
188+ 1 . ** Partial ViewModel Class** : Extends your class to inherit from ` BaseViewModel `
189+ 2 . ** Command Classes** : Each ` [Command] ` method gets a corresponding command class that inherits from ` BaseCommand `
190+ 3 . ** Command Properties** : Properties that expose the commands for data binding (lazily initialized)
191+ 4 . ** Observable Properties** : Properties with ` INotifyPropertyChanged ` support for ` [Bind] ` fields
159192
160193All generated code is available in IntelliSense and can be debugged normally.
161194
@@ -164,44 +197,48 @@ All generated code is available in IntelliSense and can be debugged normally.
164197** Your Code:**
165198``` csharp
166199[ViewModel ]
167- public partial class MyViewModel : BaseViewModel
200+ public partial class MyViewModel
168201{
169202 [Command ]
170203 public void DoSomething () => Console .WriteLine (" Done!" );
171204}
172205```
173206
174- ** Generated Code :**
207+ ** Generated ViewModel Extension :**
175208``` csharp
176- public partial class MyViewModel
209+ public partial class MyViewModel : BaseViewModel
177210{
178- private DoSomethingCommand ? _doSomethingCommand ;
179- public DoSomethingCommand DoSomethingCommand => _doSomethingCommand ??= new DoSomethingCommand (this );
211+ private Command_DoSomething ? _DoSomethingCommand { get ; set ; }
212+ public Command_DoSomething DoSomethingCommand => _DoSomethingCommand ??= new (this );
180213}
214+ ```
181215
182- public sealed class DoSomethingCommand : BaseCommand
216+ ** Generated Command Class:**
217+ ``` csharp
218+ public sealed class Command_DoSomething : BaseCommand
183219{
184- private readonly MyViewModel _viewModel ;
220+ private readonly MyViewModel vm ;
185221
186- public DoSomethingCommand (MyViewModel viewModel )
222+ public Command_DoSomething (MyViewModel vm )
187223 {
188- _viewModel = viewModel ;
224+ this . vm = vm ;
189225 }
190226
191227 public override void Execute (object ? parameter )
192228 {
193- _viewModel .DoSomething ();
229+ vm .DoSomething ();
194230 }
195231}
196232```
197233
198234## Best Practices
199235
200- 1 . ** Inherit from BaseViewModel** : Always inherit from ` BaseViewModel ` for proper ` INotifyPropertyChanged ` support
201- 2 . ** Use Partial Classes** : Mark your view models as ` partial ` to allow source generation
202- 3 . ** Async Commands** : For async operations, use ` async void ` in command methods
203- 4 . ** Parameter Validation** : Always validate parameters in command methods
204- 5 . ** Dependency Injection** : Use constructor injection for services and dependencies
236+ 1 . ** Use Partial Classes** : Always mark your view models as ` partial ` to allow source generation
237+ 2 . ** Apply ViewModel Attribute** : Use ` [ViewModel] ` on your class - the generator automatically makes it inherit from ` BaseViewModel `
238+ 3 . ** Field Naming** : Use underscore prefixes for fields marked with ` [Bind] ` (e.g., ` _title ` becomes ` Title ` property)
239+ 4 . ** Async Commands** : For async operations, use ` async void ` in command methods
240+ 5 . ** Parameter Validation** : Commands receive parameters through the ` Execute(object? parameter) ` method in the generated class
241+ 6 . ** Dependency Injection** : Use constructor injection for services and dependencies
205242
206243## Troubleshooting
207244
@@ -211,8 +248,8 @@ If the source generator isn't creating commands:
211248
2122491 . Ensure you have the ` [ViewModel] ` attribute on your class
2132502 . Make sure the class is marked as ` partial `
214- 3 . Verify you're inheriting from ` BaseViewModel `
215- 4 . Check that methods have the ` [Command ] ` attribute
251+ 3 . Check that methods have the ` [Command] ` attribute and are public
252+ 4 . Verify fields have the ` [Bind ] ` attribute for observable properties
2162535 . Clean and rebuild your solution
217254
218255### Missing Commands in XAML
@@ -223,9 +260,15 @@ If commands aren't appearing in XAML IntelliSense:
2232602 . Check that the generated files are created (enable ` <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles> ` to see them)
2242613 . Ensure proper namespace imports in XAML
225262
263+ ### Common Issues
264+
265+ - ** Fields not generating properties** : Make sure fields are marked with ` [Bind] ` and are private
266+ - ** Commands not working** : Ensure methods are public and marked with ` [Command] `
267+ - ** CanExecute not working** : Verify the method name in ` CanExecuteMethodName ` exists and is public with bool return type
268+
226269## Requirements
227270
228- - .NET 8.0 or .NET 9.0
271+ - .NET 8.0 or .NET 9.0 (Windows targets only)
229272- Windows (WPF applications only)
230273- C# 10.0 or later
231274
@@ -237,6 +280,12 @@ MIT License - see LICENSE file for details.
237280
238281Contributions are welcome! Please feel free to submit issues and pull requests.
239282
240- ## Related Packages
283+ ## Repository
284+
285+ - ** 🏠 GitHub** : [ https://github.com/DerekGooding/SimpleViewModel ] ( https://github.com/DerekGooding/SimpleViewModel )
286+ - ** 📦 NuGet** : [ https://www.nuget.org/packages/SimpleViewModel/ ] ( https://www.nuget.org/packages/SimpleViewModel/ )
287+ - ** 🐛 Issues** : [ https://github.com/DerekGooding/SimpleViewModel/issues ] ( https://github.com/DerekGooding/SimpleViewModel/issues )
288+
289+ ---
241290
242- - ** SimpleInjection ** : Companion dependency injection container with automatic service discovery
291+ * Built with ❤️ for the WPF community *
0 commit comments