Cooper
Cooper

Reputation: 31

Button Command Not Fire the Method in .Net MAUI

I am new at .Net MAUI and MVVM struct. I have MainPage.xaml and DeletePage.xaml and have 1 button in both pages to fire DeleteColor method in my MainViewModel.cs by command. I can fire the DeleteColor method from the button placed in MainPage.xaml, but not from the button in DeletePage.

MainPage.xaml:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiAppYotubeDersi.MainPage"
             xmlns:viewmodel="clr-namespace:MauiAppYotubeDersi.ViewModel"
             x:DataType="viewmodel:MainViewModel"
             >
    


        <CollectionView ItemsSource="{Binding ColorItems}">
            

            <CollectionView.ItemTemplate>
                <DataTemplate x:DataType="{x:Type x:String}">
                    <Grid Padding="0, 4"
                    ColumnDefinitions=".80*,.20*">

                        <Frame Grid.Column="0"
                               Grid.RowSpan="2">


                            <Label Text="{Binding .}"
                                   x:Name="lbl_colorName"
                                   FontSize="Medium">
                                <Label.GestureRecognizers>
                                    <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped" >
                                        
                                    </TapGestureRecognizer>
                                </Label.GestureRecognizers>
                            </Label>

                        </Frame>

                        <Button x:Name="btn2"
                                Grid.Column="1"
                                Text="X"
                                BackgroundColor="Red"
                                Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:MainViewModel}}, Path=DeleteColorCommand}"
                                CommandParameter="{Binding .}"/>

                    </Grid>
                </DataTemplate>
            </CollectionView.ItemTemplate>

        </CollectionView>
 
</ContentPage>

DeletePage.xaml:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
           xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
           x:Class="MauiApp.DeletePage"
           xmlns:viewmodel="clr-namespace:MauiApp.ViewModel"
           x:DataType="viewmodel:MainViewModel"
           Title="DeleteColor">
  <VerticalStackLayout>
      
      <Entry x:Name="ent_DeleteColor"
             VerticalOptions="Center" 
             HorizontalOptions="Center"
             Text="a"
             />

      <Button x:Name="btn"
              Text="X"
              Command="{Binding DeleteColorCommand}"
              CommandParameter="{Binding Source={x:Reference ent_DeleteColor}, Path=Text}"/>
      
  </VerticalStackLayout>
</ContentPage>

MainViewModel.cs:

    public partial class MainViewModel : ObservableObject
 {
     [ObservableProperty]
     string color;


        [ObservableProperty]
        ObservableCollection<string> colorItems;

        public MainViewModel()
     {
         ColorItems = new ObservableCollection<string>();
     }

     [RelayCommand]
     void DeleteColor(string color)
     {
         if (colorItems.Contains(color))
         {
             ColorItems.Remove(color);
    Color = string.Empty;
}
        }
 }

Upvotes: 0

Views: 248

Answers (1)

Jianwei Sun - MSFT
Jianwei Sun - MSFT

Reputation: 4332

Well, according to your comments, as a wiki answer:

Setting BindingContext for DeletePage can fix the problem.

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
           xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
           x:Class="MauiApp.DeletePage"
           xmlns:viewmodel="clr-namespace:MauiApp.ViewModel"
           x:DataType="viewmodel:MainViewModel"
           Title="DeleteColor">
     <ContentPage.BindingContext>
           <viewmodel:MainViewModel/>
     </ContentPage.BindingContext>

or

public DeletePage()
{
    InitializeComponent();
    BindingContext = new MainViewModel();
}

It's worth mentioning that if you want to keep only one instance of the MainViewModel for the entire duration of the program, you can use dependency injection (MAUI is already built-in). Like this:

In MauiProgram.cs:

public static MauiApp CreateMauiApp()
{
    var builder = MauiApp.CreateBuilder();
    builder
        .UseMauiApp<App>()
        .ConfigureFonts(fonts =>
        {
            fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
            fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
        })
        .Services.AddSingleton<MainViewModel>()
        .AddTransient<MainPage>()
        .AddTransient<DeletePage>();
     ........

And set BindingContext for pages:

public MainPage(MainViewModel viewModel)
{
    InitializeComponent();
    BindingContext = viewModel;
}

public DeletePage(MainViewModel viewModel)
{
    InitializeComponent();
    BindingContext = viewModel;
}

Upvotes: 0

Related Questions