Skip to content

Commit 92a09e4

Browse files
committed
update readme
1 parent 6d95493 commit 92a09e4

File tree

2 files changed

+108
-57
lines changed

2 files changed

+108
-57
lines changed

README.md

Lines changed: 97 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
# SimpleViewModel
1+
# SimpleViewModel
22

33
A 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;
2843
using 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

154186
SimpleViewModel 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

160193
All 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

212249
1. Ensure you have the `[ViewModel]` attribute on your class
213250
2. 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
216253
5. Clean and rebuild your solution
217254

218255
### Missing Commands in XAML
@@ -223,9 +260,15 @@ If commands aren't appearing in XAML IntelliSense:
223260
2. Check that the generated files are created (enable `<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>` to see them)
224261
3. 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

238281
Contributions 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*

SimpleViewModel/SimpleViewModel.csproj

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,22 @@
1313
<Authors>Derek Gooding</Authors>
1414
<Company>Derek Gooding</Company>
1515
<Description>
16-
A lightweight dependency injection container with automatic service discovery and powerful source generation for content management.
17-
Features attribute-based registration ([Singleton], [Scoped], [Transient]), automatic enum generation from collections,
18-
type-safe content access, and Roslyn analyzers for performance optimization.
16+
A lightweight WPF MVVM framework with automatic source generation that eliminates boilerplate code.
17+
Features attribute-based command generation ([Command]), automatic observable property creation from fields ([Bind]),
18+
and compile-time code generation with zero runtime reflection. Built specifically for WPF applications
19+
with proper CommandManager integration and INotifyPropertyChanged support.
1920
</Description>
2021
<PackageTags>
21-
dependency-injection;DI;IoC;container;source-generator;roslyn;analyzer;
22-
content-management;enum-generation;performance;csharp;dotnet;
23-
singleton;scoped;transient;service-locator;automatic-registration;
24-
type-safety;code-generation;lightweight;minimal;simple
22+
wpf;mvvm;viewmodel;source-generator;roslyn;command;binding;
23+
inotifypropertychanged;icommand;observable;properties;
24+
code-generation;compile-time;zero-boilerplate;csharp;dotnet;
25+
commandmanager;databinding;wpf-framework;lightweight;
26+
attribute-based;partial-class;baseviewmodel;basecommand
2527
</PackageTags>
2628

2729
<Summary>
28-
Lightweight DI container with source generation - automatic service discovery,
29-
enum generation from content collections, and performance-optimized analyzers.
30+
Lightweight WPF MVVM framework with source generation - automatic command and observable property generation
31+
from attributes, eliminating boilerplate code while maintaining full type safety and IntelliSense support.
3032
</Summary>
3133

3234
<PackageLicenseExpression>MIT</PackageLicenseExpression>

0 commit comments

Comments
 (0)