Passing an Object from a List to Another Page in MAUI MVVM .NET 9 [GamesCatalog] - Part 6

Previous part: Infinite Scroll and Loading Indicator in ListView in MAUI MVVM .NET 9 [GamesCatalog] - Part 5

Step 1. Let's create the page responsible for adding a game to our database.

Step 1.1. Create the ContentPage and the ViewModel.

ViewModel

Step 1.2. AddGameVM.

public partial class AddGameVM : ViewModelBase
{
}

Step 1.3. Binding the ViewModel to AddGame.xaml.cs.

public AddGame(AddGameVM addGameVM)
{
	InitializeComponent();

    BindingContext = addGameVM;
}

Step 1.4. Define the route in MauiProgram.

MauiProgram

Step 2. Let's create a function to handle tapping on a list item.

List item

Step 2.1. In IGDBResults, we'll define the function to pass the selected UIIGDBGame object to AddGame.

private void ListView_ItemTapped(object sender, ItemTappedEventArgs e)
{
    if (e.Item is UIIGDBGame tappedItem)
        Shell.Current.GoToAsync($"{nameof(AddGame)}", true, new Dictionary<string, object>
        {
            { "Game", tappedItem }
        });
}

Step 2.2. Now, our add game page is accessible.

Note. I debug as a Windows App for the sake of speed when running the system multiple times during development. You always have the option to compile for Android or, if you have a Mac/iPhone available, for iOS. Choose whatever is more comfortable for you to focus on.

I set the app window size to make development more comfortable on a Windows machine by defining it in the Windows/App.xaml.cs file.

Windows machine

Code

const int WindowWidth = 600;
const int WindowHeight = 800;

/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
    this.InitializeComponent();

    Microsoft.Maui.Handlers.WindowHandler.Mapper.AppendToMapping(nameof(IWindow), (handler, view) =>
    {
#if WINDOWS
        IWindow mauiWindow = handler.VirtualView;
        Microsoft.UI.Xaml.Window nativeWindow = handler.PlatformView;
        nativeWindow.Activate();
        IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(nativeWindow);
        WindowId windowId = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(windowHandle);
        AppWindow appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(windowId);
        appWindow.Resize(new SizeInt32(WindowWidth, WindowHeight));
#endif
    });
}

Step 3. Let's read the UIIGDBGame object passed to AddGameVM.

Step 3.1. To do this, we'll make AddGameVM inherit from IQueryAttributable and use the ApplyQueryAttributes function.

public partial class AddGameVM : ViewModelBase, IQueryAttributable
{
    private UIIGDBGame Game { get; set; }

    public async void ApplyQueryAttributes(IDictionary<string, object> query)
    {
        if (query is not null)
        {
            if (query.TryGetValue("Game", out object game))
            {
                if (game is not null and UIIGDBGame uiGame)
                {
                    Game = uiGame;
                }
            }
        }
    }
}

Step 3.2. We'll create the variables to bind with the front end and assign their values.

private UIIGDBGame Game { get; set; }

public string Id = "", name = "", releaseDate = "", coverUrl = "", platforms = "";

public string Name
{
    get => name;
    set => SetProperty(ref name, value);
}

public string ReleaseDate
{
    get => releaseDate;
    set => SetProperty(ref releaseDate, value);
}

public string CoverUrl
{
    get => coverUrl;
    set => SetProperty(ref coverUrl, value);
}

public string Platforms
{
    get => platforms;
    set => SetProperty(ref platforms, value);
}

public async void ApplyQueryAttributes(IDictionary<string, object> query)
{
    if (query is not null)
    {
        if (query.TryGetValue("Game", out object? game))
        {
            if (game is not null and UIIGDBGame uiGame)
            {
                Game = uiGame;

                Id = Game.Id;
                Name = Game.Name;
                ReleaseDate = Game.ReleaseDate;
                CoverUrl = Game.CoverUrl;
                Platforms = Game.Platforms;
            }
        }
    }
}

Step 4. Let's work on AddGame.xaml.

Step 4.1. As usual, we add the DataType and define the base style.

xmlns:vm="clr-namespace:GamesCatalog.ViewModels"
Title=""
x:DataType="vm:AddGameVM"
Style="{StaticResource ContentPage}"

Step 4.2. We'll add a base color for secondary labels in the UI in Colors.xaml.

<Color x:Key="SecondaryLabelColor">#98BDD3</Color>

Step 4.3. We'll create the grid with the labels and the image of the selected game.

Step 4.3.1. Code for AddGame.xaml.

<?xml version="1.0" encoding="utf-8"?>
<ContentPage
    x:Class="GamesCatalog.Views.AddGame"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:vm="clr-namespace:GamesCatalog.ViewModels"
    x:DataType="vm:AddGameVM"
    Style="{StaticResource ContentPage}">

    <VerticalStackLayout>
        <ScrollView>
            <Border Style="{StaticResource BorderPrimary}">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="auto" />
                        <RowDefinition Height="auto" />
                        <RowDefinition Height="auto" />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>

                    <Label
                        Grid.ColumnSpan="2"
                        Margin="0,0,0,10"
                        FontAttributes="Bold"
                        FontSize="20"
                        HorizontalOptions="Center"
                        Text="{Binding Name}"
                        TextColor="White" />

                    <Image
                        Grid.Row="1"
                        Margin="0,0,0,5"
                        Aspect="AspectFit"
                        HeightRequest="320"
                        Source="{Binding CoverUrl}" />

                    <VerticalStackLayout Grid.Row="2" Grid.Column="1">
                        <Label
                            Padding="0,0,0,5"
                            FontSize="15"
                            Text="{Binding ReleaseDate, StringFormat='Release: {0:F0}'}"
                            TextColor="{StaticResource SecondaryLabelColor}" />

                        <Label
                            Padding="0,0,0,5"
                            FontSize="15"
                            Text="{Binding Platforms, StringFormat='Platforms: {0:F0}'}"
                            TextColor="{StaticResource SecondaryLabelColor}" />
                    </VerticalStackLayout>
                </Grid>
            </Border>
        </ScrollView>
    </VerticalStackLayout>
</ContentPage>

Output

Step 4.4. Let's add the game description to fill this page.

Step 4.5. Add the summary to the IGDBGamesAPIRepo search.

IGDBGamesAPIRepo

Step 4.6. Add the IGDBGame model and the front-end UIIGDBGame model.

UIIGDBGame model

Step 4.7. Add the summary to the front-end list creation.

Front-end list creation

Step 4.8. And we'll add it to the front end in AddGame.xaml.

<?xml version="1.0" encoding="utf-8"?>
<ContentPage
    x:Class="GamesCatalog.Views.AddGame"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:vm="clr-namespace:GamesCatalog.ViewModels"
    x:DataType="vm:AddGameVM"
    Style="{StaticResource ContentPage}">

    <VerticalStackLayout>
        <ScrollView>
            <Border Style="{StaticResource BorderPrimary}">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="auto" />
                        <RowDefinition Height="auto" />
                        <RowDefinition Height="auto" />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>

                    <Label
                        Grid.ColumnSpan="2"
                        Margin="0,0,0,10"
                        FontAttributes="Bold"
                        FontSize="20"
                        HorizontalOptions="Center"
                        Text="{Binding Name}"
                        TextColor="White" />

                    <Image
                        Grid.Row="1"
                        Margin="0,0,0,5"
                        Aspect="AspectFit"
                        HeightRequest="320"
                        Source="{Binding CoverUrl}" />

                    <VerticalStackLayout Grid.Row="2" Grid.Column="1">
                        <Border
                            Margin="0,0,0,5"
                            Padding="10"
                            Background="Transparent"
                            Stroke="#2B659B"
                            StrokeShape="RoundRectangle 10">
                            <Label
                                Padding="0,0,0,5"
                                FontAttributes="Italic"
                                FontSize="12"
                                Text="{Binding Summary}"
                                TextColor="{StaticResource SecondaryLabelColor}" />
                        </Border>

                        <Label
                            Padding="0,0,0,5"
                            FontSize="15"
                            Text="{Binding ReleaseDate, StringFormat='Release: {0:F0}'}"
                            TextColor="{StaticResource SecondaryLabelColor}" />

                        <Label
                            Padding="0,0,0,5"
                            FontSize="15"
                            Text="{Binding Platforms, StringFormat='Platforms: {0:F0}'}"
                            TextColor="{StaticResource SecondaryLabelColor}" />
                    </VerticalStackLayout>
                </Grid>
            </Border>
        </ScrollView>
    </VerticalStackLayout>
</ContentPage>

Step 4.9. Now, we have the summary field on the game registration screen.

Registration screen

Next part:  Using Icon Fonts in MAUI .NET 9 [GamesCatalog] - Part 7

Code on git: GamesCatalog git

Up Next
    Ebook Download
    View all
    Learn
    View all