Model-View-Update (MVUX)
Model-View-Update has become an increasingly popular choice for developers looking to have a more functional approach to building user interfaces. In this module, we will be looking at how to use the MVUX pattern to build our UI. MVUX is a pattern that is similar to the MVU pattern but has been specifically designed to work with data binding.
To learn more about MVUX, refer to the MVUX Overview.
Getting Started
Create a new record called MainModel
using the following code that creates two IState
properties that represent whether the application is using the dark theme (IsDark
) and the current Calculator
instance:
namespace SimpleCalculator;
public partial record MainModel
{
public MainModel()
{
Calculator = State.Value(this, () => new Calculator());
IsDark = State<bool>.Value(this, () => false);
}
public IState<bool> IsDark { get; }
public IState<Calculator> Calculator { get; }
public async ValueTask InputCommand(string key, CancellationToken ct) =>
await Calculator.Update(c => c?.Input(key), ct);
}
Binding to properties in the UI
With our model created we will now need to set up our DataContext and create some bindings.
To start let's set the DataContext in the MainPage.xaml.cs (code behind).
public partial class MainPage : Page
{
public MainPage()
{
InitializeComponent();
DataContext = new MainViewModel();
}
}
You'll notice that we didn't create an instance of MainModel
but rather we created a MainViewModel
. This is the X
in MVUX
, it is a generated class that provides the glue between what XAML data bindings expect and the properties exposed by MainModel
.
Feeds & Commands
In addition to the IState
, sometimes we may need to create composite properties and execute commands. MVUX makes this simple with the IFeed
and automatically detects public methods for commands. SimpleCalc will not make use of IFeed
as it is not needed, for more information on this topic, be sure to check out the documentation: Using a FeedView.
The button inputs from the Calculator are handled via the Input
method, which is exposed as an ICommand
by MVUX.
With our UI updated, we can run the app again and press the buttons, resulting in a calculated output - We now have a functioning calculator.