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 we need to replace the temporary DataContext class we created earlier. It's also important to note here that we will not initialize the MainModel since we need the X
in MVUX
. For this, we will use the generated MainViewModel
class. You can do a Find/Replace to replace all references to TempDataContext
with MainViewModel
, and then remove the TempDataContext
class.
public MainPage()
{
this.DataContext(new MainViewModel(), (page, vm) => page
.Content(...));
}
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.