fluentmvvm 0.6.1-alpha

Suggested Alternatives

CommunityToolkit.Mvvm

Additional Details

It is now recommended to use Microsoft's MVVM Community Toolkit as a preferred alternative to this package. Its source generators allow to write boilerplate-free view models without any runtime penalty.

This is a prerelease version of fluentmvvm.
dotnet add package fluentmvvm --version 0.6.1-alpha
NuGet\Install-Package fluentmvvm -Version 0.6.1-alpha
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="fluentmvvm" Version="0.6.1-alpha" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add fluentmvvm --version 0.6.1-alpha
#r "nuget: fluentmvvm, 0.6.1-alpha"
#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.
// Install fluentmvvm as a Cake Addin
#addin nuget:?package=fluentmvvm&version=0.6.1-alpha&prerelease

// Install fluentmvvm as a Cake Tool
#tool nuget:?package=fluentmvvm&version=0.6.1-alpha&prerelease

fluentmvvm

An easy-to-use, fast ViewModelBase providing an intuitive fluent API to express property setters naturally.

Contents

Features

To make use of fluentmvvm's features, the first step is to download the NuGet package.

Then simply let your view models inherit from FluentViewModelBase.

public class PersonViewModel : FluentViewModelBase

Property Declaration

Instead of defining backing fields for each property, simply use Get() for the property getter and Set(value) for the property setter. fluentmvvm will create the backing fields at runtime, so that one can write the following code without having to worry about the backing field for the property:

public string Name
{
    get => this.GetString();
    set => this.Set(value);
}

Set raises a PropertyChanged event only if the new value is different from the old value.

There are overloads such as GetBoolean, GetInt32, etc. for all primitive types as well as GetDecimal, GetDateTime, and GetString. The Get<T> method can be used for all other value and reference types (structs, enums, classes).

Remarks

Note that this mechanism only works for public instance properties with a set accessor.

Not creating backing fields at runtime

If you do not want backing fields to be created at runtime, you can pass false to the createBackingFields parameter of FluentViewModelBase. You can then still use the fluent API with the Set<T>(T value, ref T oldValue, ...) overload.

Dependencies between properties

For cases where a (computed) property's value depends on other properties' values, Affects can be used after Set.

It would raise a PropertyChanged event for the specified property if the new value was different from the old one.

public string FullName => $"{this.FirstName} {this.LastName}";

public string FirstName
{
    get => this.GetString();
    set => this.Set(value)
               .Affects(nameof(this.FullName));
}

public string LastName
{
    get => this.GetString();
    set => this.Set(value)
               .Affects(nameof(this.FullName));
}

Dependencies between properties and commands

For cases when a commands CanExecute is based on some property's value, Affects can be used with the command to raise the CanExecuteChanged event for.

public ICommand BuyThingsCommand { get; }

public int Balance
{
    get => this.GetInt32();
    set => this.Set(value)
             .Affects(this.BuyThingsCommand);
}

Remarks

Affects accepts a parameter of type ICommand. However, if the command does not contain a

public void RaiseCanExecuteChanged()

method, an exception is thrown. You can also derive from the interface IWpfCommand provided by fluentmvvm to make sure that the method mentioned above exists on your command implementations.

Fluent API

FluentViewModelBase provides a fluent API that can be used in property setters.

this.When(<condition>)        // never or once
    .Set(value)               // exactly once
    .Affects(<property name>) // never, once or many times
    .Affects(<command>)       // never, once or many times
    .WasUpdated();            // never or once

Overview

  • If the condition passed to When evaluates to false, the calls to Set and Affects do not execute anything.

  • Set checks whether the new value differs from the current value of the property. If it does differ, it sets the value to the property and raises a PropertyChanged event. If it does not, nothing happens, and all following Affects calls do not execute either.

  • When expressing a dependency between one property and another, Affects can be used with the name of the property to raise a PropertyChanged event for. The event is raised only if the new value of the property differed from the old value.

  • If your command implementations derive from IWpfCommand, dependencies between properties and commands can also be expressed using Affects. That way, when the new value of the property differs from the old value, a CanExecuteChanged event is raised for the command.

  • WasUpdated returns a bool value indicating whether the property value was updated (and thus whether a PropertyChanged event was raised for the property).

License

(c) Thomas Flinkow 2019 - 2021 · GitHub · email

Distributed under the MIT license. See LICENSE for more information.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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.6.1-alpha 269 2/2/2021
0.6.0-alpha 201 2/2/2021
0.5.0-alpha 235 1/2/2021
0.3.2-alpha 366 3/19/2020
0.3.1-alpha 328 3/19/2020
0.3.0-alpha 342 3/8/2020
0.2.0-alpha 340 12/11/2019

- Removed the AfterSet() method
- Added an AfterSet<T>(T value, string propertyName) method