0

I have the following XAML

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
             x:Class="MyApp.Pages.Locations.LocationsList"
             xmlns:mvvm="clr-namespace:MvvmHelpers;assembly=MvvmHelpers"
             xmlns:telerik="http://schemas.telerik.com/2022/xaml/maui">
    <ContentPage.ToolbarItems>
        <ToolbarItem Text="Add" Command="{Binding AddCommand}" />
    </ContentPage.ToolbarItems>
    <ContentPage.Behaviors>
        <toolkit:EventToCommandBehavior EventName="Appearing" Command="{Binding LoadCommand}" />
    </ContentPage.Behaviors>
    <ContentPage.Resources>
        <ResourceDictionary>
            <toolkit:SelectedItemEventArgsConverter x:Key="SelectedItemEventArgsConverter" />
        </ResourceDictionary>
    </ContentPage.Resources>
    <ListView BackgroundColor="Transparent"
              CachingStrategy="RecycleElement"
              ItemsSource="{Binding Locations}"
              SelectedItem="{Binding SelectedLocation, Mode=TwoWay}"
              SeparatorVisibility="None"
              HasUnevenRows="True">
        <ListView.Behaviors>
            <toolkit:EventToCommandBehavior
                        EventName="ItemSelected"
                        EventArgsConverter="{StaticResource SelectedItemEventArgsConverter}"
                        Command="{Binding SelectCommand}"/>
        </ListView.Behaviors>
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <ViewCell.ContextActions>
                        <MenuItem Text="Delete" IsDestructive="True"
                                          Command="{Binding DeleteCommand}"
                                          CommandParameter="{Binding .}" />
                        <MenuItem Text="Edit"  Command="{Binding EditCommand}"
                                    CommandParameter="{Binding .}" />
                    </ViewCell.ContextActions>
                    <Grid Padding="10">
                        <Frame>
                            <StackLayout Orientation="Horizontal">
                                <Image Source="map.png" WidthRequest="40" />
                                <StackLayout Orientation="Vertical" Padding="10,0,0,0">
                                    <Label VerticalOptions="Center"
                                       FontSize="Medium"
                                       Text="{Binding Name}" />
                                    <Label VerticalOptions="Center"
                                       FontSize="Micro"
                                       Text="This is where the address will go." />
                                </StackLayout>
                            </StackLayout>
                        </Frame>
                    </Grid>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</ContentPage>

My ViewModel uses the Maui Community Toolkit and has 4 AsyncCommands defined

  • LoadCommand
  • SaveCommand
  • DeleteCommand
  • EditCommand

The LoadCommand and SaveCommand work perfectly but the DeleteCommand and EditCommand do not fire. I assume it's something to do with the commands being on the viewmodel and NOT on the item source model. How do I get it to trigger the AsyncCommands on the viewmodel?

Thanks

Steve Borman
  • 337
  • 1
  • 10
  • https://learn.microsoft.com/en-us/dotnet/maui/fundamentals/data-binding/relative-bindings?view=net-maui-7.0 – Jason Jan 16 '23 at 14:35

1 Answers1

0

For this, you can check document Define MenuItem behavior with MVVM.

The MenuItem class supports the Model-View-ViewModel (MVVM) pattern through BindableProperty objects and the ICommand interface. The following XAML shows MenuItem instances bound to commands defined on a viewmodel:

<?xml version="1.0" encoding="utf-8" ?> 
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:viewmodels="clr-namespace:MenuItemDemos.ViewModels"
             mc:Ignorable="d"
             x:Class="MenuItemDemos.MenuItemXamlMvvmPage"
             x:Name="myContentpage"
             Padding="10"
             Title="MenuItem XAML MVVM Demo"
             >
    
    <ContentPage.BindingContext>
        <viewmodels:ListPageViewModel />
    </ContentPage.BindingContext>

    <StackLayout>
        <Label Text="Reveal the context menu by right-clicking (UWP), long-pressing (Android), or swiping (iOS) an item in the following list." />
        <Label Text="{Binding Message}"
               TextColor="Red"
               HorizontalOptions="CenterAndExpand"
               VerticalOptions="Start" />
        <ListView ItemsSource="{Binding Items}"
                  HorizontalOptions="CenterAndExpand"
                  VerticalOptions="CenterAndExpand">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <ViewCell.ContextActions>
                            <MenuItem Text="Edit"
                                      IconImageSource="icon.png"
                                      Command="{Binding Source={x:Reference myContentpage}, Path=BindingContext.EditCommand}"
                                      CommandParameter="{Binding .}"/>
                            <MenuItem Text="Delete"
                                      Command="{Binding Source={x:Reference myContentpage}, Path=BindingContext.DeleteCommand}"
                                      CommandParameter="{Binding .}"/>
                        </ViewCell.ContextActions>
                        <Label Text="{Binding .}" />
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage>

The viewmodel(ListPageViewModel.cs) contains the commands referenced in the XAML:

public class ListPageViewModel : INotifyPropertyChanged
{
    ...

    public ICommand EditCommand => new Command<string>((string item) =>
    {
        Message = $"Edit command was called on: {item}";
    });

    public ICommand DeleteCommand => new Command<string>((string item) =>
    {
        Message = $"Delete command was called on: {item}";
    });
}
Jessie Zhang -MSFT
  • 9,830
  • 1
  • 7
  • 19