mansik / MauiApp3

.NET MAUI UI , Data Binding with MVVM & XAML, Navigating Between Page

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

MauiApp1

About

(Example).NET MAUI for Beginners

Environment

  • IDE: Visual Studio 2022
  • Language: C#
  • Applied Project Template: .MAUI APP
  • NuGet
    • CommunityToolkit.Mvvm
  • Third Party Libraries: x
  • DataBase: x

Reference

Process

  • install Nuget CommunityToolkit.Mvvm
  • create ViewModel Folder and MainViewModel.cs class
  • MainViewModel.cs: inherit from ObservableObject
     public partial class MainViewModel : ObservableObject 
    • add ObservableProperty, RelayCommand
       public MainViewModel()
       	{
       		Items = new ObservableCollection<string>();
       	}
      
       	[ObservableProperty]
       	ObservableCollection<string> items;
      
       	[ObservableProperty]
       	string? text;
      
       	[RelayCommand]
       	void Add()
       	{
       		if (string.IsNullOrWhiteSpace(Text))
       			return;
      
       		Items.Add(Text);
      
       		// add our item
       		Text = string.Empty;
       	}
      
       	[RelayCommand]
       	void Delete(string s)
       	{
       		if (Items.Contains(s))
       		{
       			Items.Remove(s);
       		}
       	}
  • MainPage.xaml: add ViewModel and View Combine to ContentPage and Add Data Binding
    • ViewModel and View Combine to ContentPage: add xmlns:viewmodel and x:DataType
       <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            x:Class="MauiApp3.MainPage"
            xmlns:viewmodel="clr-namespace:MauiApp3.ViewModel"
            x:DataType="viewmodel:MainViewModel">
    • setting Data Binding for controls
       <Entry Grid.Row="1"
       			   Placeholder="Enter task"
       			   Text="{Binding Text}"/>
      
       <Button Grid.Row="1"
       		Grid.Column="1"
       		Text="Add"
       		Command="{Binding AddCommand}"/>
      
       <CollectionView Grid.Row="2"
       				Grid.ColumnSpan="2"
       				ItemsSource="{Binding Items}"
       				SelectionMode="None">
       	<CollectionView.ItemTemplate>
       		<DataTemplate x:DataType="{x:Type x:String}">
       			<SwipeView>
       				<SwipeView.RightItems>
       					<SwipeItems>
       						<SwipeItem Text="Delete"
       									BackgroundColor="Red"
       									Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:MainViewModel}}, Path=DeleteCommand}"
       									CommandParameter="{Binding .}"/> 
       						<!-- 기본적으로 상대 바인딩을 의미하는 상위 바인딩을 제공해야 한다.-->
       					</SwipeItems>
       				</SwipeView.RightItems>
    • setting x:DataType for DataTemplate
       <DataTemplate x:DataType="{x:Type x:String}">
  • MainPage.xaml.cs: set the BindingContext for ViewModel in MainPage
     public MainPage(MainViewModel vm)
     {
         InitializeComponent();
         BindingContext = vm;
     }
  • MauiProgram.cs: Add dependency Service(register MainPage and MainViewModel in MAUI program)
     builder.Services.AddSingleton<MainPage>(); 
     builder.Services.AddSingleton<MainViewModel>();
  • Add .Net Maui ContentPage(xaml): Add DetailPage

  • Add DetailViewModel class and inherit from ObservableObject

     public partial class DetailViewModel : ObservableObject
  • DetailPage.xaml.cs: set the BindingContext for ViewModel in DetailPage(data binding)

     public DetailPage(DetailViewModel vm)
     {
     	InitializeComponent();
     	BindingContext = vm;
     }
  • MauiProgram.cs: register DetailPage and DetailViewModel in MAUI program(Dependency injection)

     builder.Services.AddTransient<DetailPage>();
     builder.Services.AddTransient<DetailViewModel>();
  • AppShell.xaml.cs: register DetailPage with the routing system of .MAUIShell

     Routing.RegisterRoute(nameof(DetailPage), typeof(DetailPage));
  • MainPage.xaml: add Navigation when click on an item in the CollectionView (navigate when tapping and not selection)

    we don't want to use the built-in selection mode. Because we're just doing navigation, we're not actually selecting anything, I'm more like tapping on an item.

    1. add SelectionMode="None": we don't want to use the built-in selection mode
      <CollectionView Grid.Row="2"
                      Grid.ColumnSpan="2"
                      ItemsSource="{Binding Items}"
                      SelectionMode="None">
    2. add a TapGestureRecognizer on the Frame( Frame is housing in the label)
      <Grid Padding="0, 5">
          <Frame>
              <Frame.GestureRecognizers>
                  <TapGestureRecognizer Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:MainViewModel}}, Path=TapCommand}"
                                          CommandParameter="{Binding .}"/>
              </Frame.GestureRecognizers>
              <Label Text="{Binding .}"
                      FontSize="24"/>
          </Frame>
      </Grid>
    3. setting Data Binding in TapGestureRecognizer
      <TapGestureRecognizer Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:MainViewModel}}, Path=TapCommand}"
                              CommandParameter="{Binding .}"/>
  • MainViewModel.cs: add async Tap Pass Task and use the shell navigation(Shell.Current.GoToAsync)

     [RelayCommand]
     async Task Tap(string s)
     {
         await Shell.Current.GoToAsync(nameof(DetailPage));
     }
  • there's two ways(query property, data binding) to pass DetailPage information

    1. use query property way: await Shell.Current.GoToAsync($"{nameof(DetailPage)}?Text={s}");
      1. MainViewModel.cs
      [RelayCommand]
      async Task Tap(string s)
      {
      	// do not send informations
      	// await Shell.Current.GoToAsync(nameof(DetailPage));
      
      	// [there's two ways to pass DetailPage information]
      	//  1. query property: await Shell.Current.GoToAsync($"{nameof(DetailPage)}?Text={s}");
      	//  2. URI
      	// to send simple data type like strings and integers across
      	await Shell.Current.GoToAsync($"{nameof(DetailPage)}?Text={s}"); // [QueryProperty("Text", "Text")]
      	// await Shell.Current.GoToAsync($"{nameof(DetailPage)}?id={s}"); // [QueryProperty("Text", "id")]
      
      
      	// to send a complex data type, like a person or a car or some other data object
      	// await Shell.Current.GoToAsync($"{nameof(DetailPage)}?Text={s}",
      	//        new Dictionary<string, object>
      	//        {
      	//            {nameof(DetailPage), new object()},
      	//        });
      }
      1. How are we going to get that string into our detail view model?
        • DetailViewModel.cs: add [QueryProperty(name, queryId)]
           namespace MauiApp3.ViewModel;
          
           [QueryProperty("Text", "id")]
           // await Shell.Current.GoToAsync($"{nameof(DetailPage)}?id={s}");
        • DetailViewModel.cs: add name property of QueryProperty(name, queryId)
           public partial class DetailViewModel : ObservableObject
           {
           	[ObservableProperty]
           	string text; // "Text" property  of [QueryProperty("Text", "id")]
           }
    2. use data binding way: async Task to go back
      1. DetailViewModel.cs: add async Task
        [RelayCommand]
        async Task GoBack()
        {
        	await Shell.Current.GoToAsync("..");
        }
      2. DetailPage.xaml: add ViewModel and View Combine to ContentPage and Add Data Binding
        • ViewModel and View Combine to ContentPage: add xmlns:viewmodel and x:DataType
           <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
           			 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
           			 x:Class="MauiApp3.DetailPage"
           			 xmlns:viewmodel="clr-namespace:MauiApp3.ViewModel"
           			 x:DataType="viewmodel:DetailViewModel"
           			 Title="DetailPage">
        • add Go Back button and setting Data Binding for controls
           <Label 
           	Text="{Binding Text}"
           	FontSize="25"
           	VerticalOptions="Center" 
           	HorizontalOptions="Center" />
          
           <Button Text="Go Back"
           		Command="{Binding GoBackCommand}"/>

About

.NET MAUI UI , Data Binding with MVVM & XAML, Navigating Between Page

License:MIT License


Languages

Language:C# 100.0%