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

Chapter 8 Advanced UI Concepts

Pros

 

•\

Keeps specific code contained

•\

Provides easy return result handling

For further reading on how to use the toolkit and its Popup class, please refer to the documentation at https://learn.microsoft.com/dotnet/ communitytoolkit/maui/views/popup.

The Chosen Approach

Given the pros and cons outlined above, you might guess that you will be using the Popup class. Nope. Let’s use the overlaying-a-view approach. This is mainly because it will help to expose you to more .NET MAUI-specific concepts that I believe will be extremely valuable in building applications. However, for your own work, use the approach that best fits your scenario. I would like to emphasize that each of the above options will achieve the results needed. In fact, there could well be more options that I haven’t covered, and if you find one, I would love to hear about it.

Adding Your Overlay View

You need to add a view to your FixedBoardPage.xaml file that will present the option to the user to add a new widget to the board. Let’s open that file and add the following code inside the Grid and below the

</layouts:BoardLayout> line:

<BoxView

BackgroundColor="Black"

Opacity="0.5"

IsVisible="{Binding IsAddingWidget}" />

<Border

IsVisible="{Binding IsAddingWidget}"

224

Chapter 8 Advanced UI Concepts

HorizontalOptions="Center"

VerticalOptions="Center"

Padding="10">

<VerticalStackLayout>

<Label

Text="Add widget" FontSize="20" />

<Label Text="Widget" />

<Picker

ItemsSource="{Binding AvailableWidgets}" SelectedItem="{Binding SelectedWidget}" SemanticProperties.Description="{Binding Text, Source={x:Reference SelectTheWidgetLabel}}" SemanticProperties.Hint="Picker containing the possible widget types that can be added to the board. This is a required field." />

<Label Text="Preview" />

<ContentView

WidthRequest="250" HeightRequest="250" />

<Button

Text="Add widget"

Command="{Binding AddWidgetCommand}" SemanticProperties.Hint="Adds the selected widget to the board. Requires the 'Select the widget' field to be set." />

</VerticalStackLayout>

</Border>

225

Chapter 8 Advanced UI Concepts

The code addition results in two new controls added to the parent Grids children collection: a BoxView and a Border. The BoxView is added to provide a semi-transparent overlay on top of the rest of the application and the Border presents the content for selecting a new widget. Adding them after the BoardLayout means it will be rendered on top of the BoardLayout. This ordering is referred to as Z-index and in the majority of .NET MAUI applications, layouts are determined by the order in which the children are added to their parent. This means that the later the controls are added, the higher they will appear visually. You can modify this default behavior by using the ZIndex property where the higher the value, the higher they will appear visually. With this knowledge, you can add a binding between the IsVisible property of your new controls and a property on your view model, so your view model can control whether you are adding a widget to the board.

Let’s update your view model.

Updating Your View Model

Since you turned on compiled bindings in a previous chapter, you will now see that your code will not compile because you have not defined the properties you are binding to. So open the FixedBoardPageViewModel.cs file and make the following additions.

Add the new properties and associated backing fields into your

FixedBoardPageViewModel class.

private int addingPosition; private string selectedWidget; private bool isAddingWidget;

private readonly WidgetFactory widgetFactory;

public IList<string> AvailableWidgets => widgetFactory­ . AvailableWidgets;

226

Chapter 8 Advanced UI Concepts

public ICommand AddWidgetCommand { get; }

public ICommand AddNewWidgetCommand { get; }

public bool IsAddingWidget

{

get => isAddingWidget;

set => SetProperty(ref isAddingWidget, value);

}

public string SelectedWidget

{

get => selectedWidget;

set => SetProperty(ref selectedWidget, value);

}

Update the constructor with the new WidgetFactory dependency and set the new commands that you have added; changes are in bold.

public FixedBoardPageViewModel( WidgetTemplateSelector widgetTemplateSelector, WidgetFactory widgetFactory)

{

WidgetTemplateSelector = widgetTemplateSelector; this.widgetFactory = widgetFactory;

Widgets = new ObservableCollection<IWidgetViewModel>();

AddWidgetCommand = new Command(OnAddWidget);

AddNewWidgetCommand = new Command<int>(index =>

{

IsAddingWidget = true; addingPosition = index;

});

}

227

Chapter 8 Advanced UI Concepts

In the previous code section, you set the IsAddingWidget property to true in order to show the overlay view and you also keep a record of the index variable, which is the Position property from the Placeholder that was tapped.

Provide the method implementation for the AddWidgetCommand.

private void OnAddWidget()

{

if (SelectedWidget is null)

{

return;

}

var widgetViewModel = widgetFactory.CreateWidgetViewModel (SelectedWidget);

widgetViewModel.Position = addingPosition;

Widgets.Add(widgetViewModel);

IsAddingWidget = false;

}

Hopefully the majority of what you just added should feel familiar. The part that most likely doesn’t is the final OnAddWidget method. Let’s take a deeper look at this implementation.

The SelectedWidget property is bound to your Picker in the view. You do some initial input validation to make sure that the user has chosen a type of widget to add; otherwise, you return out of the method.

Next, you use the new dependency (widgetFactory) to create a view model for you.

Then you set its Position based on which placeholder was tapped initially.

228