↑ back to the MVVMbasics main page
Data Binding
- Attribute-based bindable property declaration for automatic INotifyPropertyChanged implementation:
[MvvmBindable] public bool IsEnabled { get; set; }
- Shortest possible set-up of bindable properties implementing INotifyPropertyChanged without using attributes:
private bool _isEnabled; public bool IsEnabled { get => _isEnabled; set => Set(ref _isEnabled, value); }
- Calling additional methods after bindable properties are updated, but only if old and new values are unequal:
private bool _isEnabled; public bool IsEnabled { get => _isEnabled; set => Set(SomeCondition, ref _isEnabled, value, SomeMethod); } private bool SomeCondition() { // This method is only called if old and new value of the IsEnabled property differ. Moreover, it is // called before the IsEnabled property is updated to its new value, allowing to abort this property // update by returning FALSE. } private void SomeMethod() { // This method is only called if old and new value of the IsEnabled property differ. Moreover, it is // called after the IsEnabled property is updated to its new value, allowing, e.g., instant updates // of other properties that depend on IsEnabled. }
Command Binding
- Easy declaration of delegate commands, with or withour command parameters:
public BaseCommand ButtonClickedCommand { get; } public MyViewmodel() { ButtonClickedCommand = CreateCommand(ButtonClickedMethod); } private void ButtonClickedMethod(object parameter) { // ... }
- Declaration and convenient testing of delegate commands that invoke asynchronous methods:
public BaseCommand ButtonClickedCommand { get; } public MyViewmodel() { ButtonClickedCommand = CreateAsyncCommand(ButtonClickedMethod); } private async Task ButtonClickedMethod() { // ... } [TestMethod] public async Task TestDoStuff() { await ButtonClickedCommand.ExecuteAsync(); }
- Platform-independent update of commands’ CanExecute properties:
[MvvmBindable] public bool IsEnabled { get; set; } public MyViewmodel() { ButtonClickedCommand = CreateCommand(ButtonClickedMethod, () => IsEnabled); }
- Direct Event to Command binding without code-behind event handlers:
<ListBox SelectionChanged="EventToCommand" mvvm:Event.Command="{Binding ListSelectionChangedCommand}" mvvm:Event.CommandParameter="{Binding ElementName=SomeControl, Path=SelectedItem}" ... />
- Automatic binding of commands to Viewmodel methods and
CanExecute
conditions:[MvvmCommandAutobinding] public sealed class MyViewmodel : BaseViewmodel { public BaseCommand ButtonClickCommand { get; set; } public Expression<Func<bool>> CanButtonClick => () => SomeCondition == true; private void ButtonClick() { // logic goes here... } }
Tight coupling of Viewmodel and View
- Easy binding of pages and windows to Viewmodels:
[MvvmNavigationTarget(typeof(MyViewmodel))] public sealed partial class MyPage : BaseView { // ... }
- Advanced binding of Windows 10 pages to Viewmodels:
public sealed partial class MyPage : BaseView, IBindableView<MyViewmodel> { public MyViewmodel Vm { get; set; } // ... }
- Reacting to page / window navigation events directly within Viewmodel code:
public sealed class MyViewmodel : BaseViewmodel { public override void OnNavigatedTo(ParameterList uriParameters, ParameterList parameters, ViewState viewState) { // ... } public override bool CancelNavigatingFrom(ViewState viewState) { // ... } public override void OnNavigatedFrom(ViewState viewState) { // ... } }
- Standardization of page / window status through all platforms:
public override void OnNavigatedTo(ParameterList uriParameters, ParameterList parameters, ViewState viewState) { switch (viewState) { case ViewState.Activated: // ... break; case ViewState.Reactivated: // ... break; case ViewState.Shown: // ... break; case ViewState.Awakened: // ... break; } } public override void OnNavigatedFrom(ParameterList uriParameters, ParameterList parameters, ViewState viewState) { switch (viewState) { case ViewState.Deactivated: // ... break; case ViewState.Closed: // ... break; case ViewState.Hidden: // ... break; case ViewState.Hibernated: // ... break; } }
Platform-independent navigation code
- Global, platform-independent navigator service that allows page / window navigation from within Viewmodel code:
var navigator = ServiceLocator.Retrieve<INavigatorService>(); navigator.NavigateTo<AnotherViewmodel>();
- Passing parameters of complex types between pages / windows:
navigator.NavigateTo<AnotherViewmodel>(new Parameter("search_time", DateTime.Now));
public override void OnNavigatedTo(ParameterList uriParameters, ParameterList parameters, ViewState viewState) { DateTime searchTime; parameters.TryGetDateTime("search_time", out searchTime); }
Global access to business logic through distinguished MVVM Services:
- Centrally stored platform-independent services:
[MvvmService] public class SampleService : IService { // Service methods follow here... }
- Common interfaces defining platform-specific services:
public interface IPlatformspecificService : IService { // Signatures of service methods follow here... }
[MvvmService] public class PlatformspecificService : IPlatformspecificService { // Implementations of service methods (as defined in the service interface) follow here... }
- Global service container for registering platform-independent and platform-specific services (that can be replaced by any 3rd party IoC container):
Services.Register<SampleService>(); Services.Register(new IPlatformspecificService()); public MyViewmodel(SampleService sampleService, IPlatformspecificService platformspecificService) { // ... }