MvvmLib.CodeGenerators
Allows to generate code with Source Generators
Support: MvvmLib, Prism (installation detected)
Class Level Attributes:
- Inpc attribute: to implement INotifyPropertyChanged
- BindableObject attribute: allows to add BindableBase Class (and implement IActiveAware for Prism)
Field Level Attribute:
- BindableProperty attribute: allows to use "Setproperty", specify properties (OnPropertyChanged/RaisePropertyChanged) and commands (RaiseCanExecuteChanged) notified when the value has changed.
Method Level Attribute:
- Command attribute: for add a DelegateCommand with CanExecute method and Name to specify a custom command name.
Comments supported on fields and methods for generated properties and commands.
Sample with MvvmLib
using MvvmLib.CodeGenerators;
namespace CodeGeneratorsSample.ViewModels
{
[BindableObject]
public partial class ShellViewModel
{
[BindableProperty(nameof(CompleteTitle))]
string _title;
[BindableProperty(CommandsToNotify = new[] { nameof(ChangeTitleCommand) })]
bool _canChange;
public ShellViewModel()
{
_title = "Initial title";
}
public string CompleteTitle
{
get { return _title + "!!!!"; }
}
[Command(CanExecute = nameof(CanChangeTitle))]
private void ChangeTitle(string title)
{
Title = title;
}
private bool CanChangeTitle(string title) => _canChange;
}
}
Prism version
using MvvmLib.CodeGenerators;
namespace CodeGeneratorsSample.ViewModels
{
[BindableObject(ImplementIActiveAware = true)]
public partial class ShellViewModel
{
[BindableProperty(nameof(CompleteTitle))]
string _title;
[BindableProperty(CommandsToNotify = new[] { nameof(ChangeTitleCommand) })]
bool _canChange;
public ShellViewModel()
{
_title = "Initial title";
}
public string CompleteTitle
{
get { return _title + "!!!!"; }
}
[Command(CanExecute = nameof(CanChangeTitle))]
private void ChangeTitle(string title)
{
Title = title;
}
private bool CanChangeTitle(string title) => _canChange;
}
}
Generated :
// generated code
using System;
using Prism;
using Prism.Mvvm;
using Prism.Commands;
namespace CodeGeneratorsSample.ViewModels
{
partial class ShellViewModel : BindableBase, IActiveAware
{
public string Title
{
get { return _title; }
set
{
if(SetProperty(ref _title, value))
{
RaisePropertyChanged("CompleteTitle");
}
}
}
public bool CanChange
{
get { return _canChange; }
set
{
if(SetProperty(ref _canChange, value))
{
ChangeTitleCommand.RaiseCanExecuteChanged();
}
}
}
private DelegateCommand<string> _changeTitleCommand;
public DelegateCommand<string> ChangeTitleCommand =>
_changeTitleCommand ?? (_changeTitleCommand = new DelegateCommand<string>(ChangeTitle, CanChangeTitle));
private bool _isActive;
/// <summary>
/// Gets or sets a value indicating whether the object is active.
/// </summary>
public bool IsActive
{
get { return _isActive; }
set
{
_isActive = value;
OnIsActiveChanged();
}
}
/// <summary>
/// Notifies that the value for <see cref="IsActive"/> property has changed.
/// </summary>
public event EventHandler IsActiveChanged;
/// <summary>
/// Notifies that the value for <see cref="IsActive"/> property has changed.
/// </summary>
protected virtual void OnIsActiveChanged() => IsActiveChanged?.Invoke(this, new EventArgs());
}
}
Xaml
<Window.DataContext>
<viewModels:ShellViewModel />
</Window.DataContext>
<Grid>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Text="{Binding Title}" FontSize="40" />
<TextBlock Text="{Binding CompleteTitle}" FontSize="40" />
<Button Command="{Binding ChangeTitleCommand}" CommandParameter="New title!">Change title</Button>
<CheckBox IsChecked="{Binding CanChange}" Content="Can change title?"/>
</StackPanel>
</Grid>