Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lawrence_shaun_introducing_net_maui_build_and_deploy_crosspl.pdf
Скачиваний:
46
Добавлен:
26.06.2023
Размер:
5.15 Mб
Скачать

Chapter 4 An Architecture to Suit You

As a maintainer on the .NET MAUI Community Toolkit, one of the packages we provide is CommunityToolkit.Maui.Markup. It provides a set of extension methods and helpers to build UIs fluently.

using CommunityToolkit.Maui.Markup; using WidgetBoard.ViewModels;

namespace WidgetBoard.Views;

public class ClockWidget : ContentView

{

public ClockWidget()

{

BindingContext = new ClockWidgetViewModel();

Content = new Label()

.Font(size: 80)

.CenterHorizontal()

.CenterVertical()

.Bind(Label.TextProperty,

nameof(ClockWidgetViewModel.Time));

}

}

This code performs the same steps as the plain C# example; however, the code is much easier to read. I am sure you can imagine that when the complexity of the UI increases, this fluent approach can really start to benefit you.

Chosen Architecture for This Book

Throughout this book, we will be using the MVVM-based architecture while building the UI through XAML.

89

Chapter 4 An Architecture to Suit You

My reasons for choosing MVVM are as follows:

•\

I have spent the last 10+ years using this architecture so

 

it certainly feels natural to me.

•\

It has been a very common way of building applications

 

over the past decade so there is an abundance of

 

resources online to assist in overcoming issues

 

around it.

•\

It is a common pattern in all Microsoft products and

 

has a proven track record.

Now that I have covered the various architecture options and decided on using MVVM, let’s proceed to adding in the specific Views and ViewModels so that it can be used inside the application. Then I will show how to start simplifying the implementation so that the code really only needs to include the core logic by avoiding having to add a lot of the boilerplate code.

Adding theViewModels

First, add a new folder to your project.

•\

Right-click the WidgetBoard project.

•\

Select Add New Folder.

•\

Enter the name ViewModels.

•\

Click Add.

This folder will house your application’s view models. Let’s proceed to adding the first one.

90

Chapter 4 An Architecture to Suit You

Adding IWidgetViewModel

The first item you need to add is an interface. It will represent all widget view models that you create in your application.

•\

Right-click the ViewModels folder.

•\

Select Add New Item.

•\

Select the Interface type.

•\

Enter the name IWidgetViewModel.

•\

Click Add.

Modify this file to the following:

namespace WidgetBoard.ViewModels;

public interface IWidgetViewModel

{

int Position { get; set; }

string Type { get; }

}

Adding BaseViewModel

This will serve as the base class for all of your view models so that you only have to write some boilerplate code once. Don’t worry; you will see how to optimize this even further!

•\

Right-click the ViewModels folder.

•\

Select Add Class.

•\

Enter the name BaseViewModel.

•\

Click Add.

91

Chapter 4 An Architecture to Suit You

You can replace the contents of the class file with the following code:

using System.ComponentModel;

using System.Runtime.CompilerServices;

namespace WidgetBoard.ViewModels;

public abstract class BaseViewModel : INotifyPropertyChanged

{

public event PropertyChangedEventHandler PropertyChanged;

protected void OnPropertyChanged([CallerMemberName] string propertyName = "")

{

PropertyChanged?.Invoke(this, new PropertyChangedEventA rgs(propertyName));

}

protected bool SetProperty<TValue>(ref TValue backingField, TValue value, [CallerMemberName] string propertyName = "")

{

if (Comparer<TValue>.Default.Compare(backingField, value) == 0)

{

return false;

}

backingField = value;

OnPropertyChanged(propertyName);

return true;

}

}

92

Chapter 4 An Architecture to Suit You

You should be familiar with the first line inside the class:

public event PropertyChangedEventHandler PropertyChanged;

This is the event definition that you must add as part of implementing the INotifyPropertyChanged interface and it serves as the mechanism for your view model to update the view.

The next method provides a mechanism to easily raise the

PropertyChanged event:

protected void OnPropertyChanged([CallerMemberName] string propertyName = "")

{

PropertyChanged?.Invoke(this, new PropertyChangedEventArgs( propertyName));

}

The OnPropertyChanged method can be called with or without passing in a value for propertyName. By passing a value in, you are indicating which property name on your view model has changed. If you do not, then the [CallerMemberName] attribute indicates that the name of caller will be used. Don’t worry if this is a little unclear right now; it will become much clearer when you add your property into your ClockWidgetViewModel so just bear with me.

The final method adds a lot of value:

protected bool SetProperty<TValue>( ref TValue backingField, TValue value,

[CallerMemberName] string propertyName = "")

{

if (Comparer<TValue>.Default.Compare(backingField, value) == 0)

{

93