ContentView as CollectionView's ItemTemplate with custom Command

Matteo Pozzato 116 Reputation points
2024-04-15T14:45:48.2866667+00:00

Hi,

I have a CollectionView that have as ItemTemplate a ContentView.

I need to pass at the XAML of the ContentView a custom Command, so I have created a BindableProperty but it remains always null.

public ICommand ApriCommand
{
    get { return (ICommand)GetValue(ApriCommandProperty); }
    set { SetValue(ApriCommandProperty, value); }
}
public static readonly BindableProperty ApriCommandProperty = BindableProperty.Create(
    propertyName: nameof(ApriCommand),
    returnType: typeof(ICommand),
    declaringType: typeof(MyItemTemplate),
    defaultValue: null,
    defaultBindingMode: BindingMode.OneWay,
    propertyChanged: (BindableObject bindable, object oldValue, object newValue) =>
    {
        {
            // never called
        }
    }
);

Then I have created the XAML for the item template:

<VerticalStackLayout Margin="0,0,0,2" >
<VerticalStackLayout.GestureRecognizers>
    <TapGestureRecognizer Command="{Binding Source={x:Reference Me}, Path=ApriCommand}" CommandParameter="{Binding .}" />
</VerticalStackLayout.GestureRecognizers>

<Grid RowDefinitions="*" ColumnDefinitions="0.5*,0.5*" Padding="5" Background="LightSkyBlue" HeightRequest="60">
    <Label 
        Grid.Column="0"
        Text="{Binding ID}"
        VerticalOptions="Center" 
        HorizontalOptions="Start" />
    <Label 
        Grid.Column="1"
        Text="{Binding Value}"
        VerticalOptions="Center" 
        HorizontalOptions="End" />
</Grid>
<BoxView HeightRequest="1" Color="Black" VerticalOptions="End" />
</VerticalStackLayout>

Then I have created a command in the ViewModel and populate the list.

public partial class ViewModel : ObservableObject
{
    [ObservableProperty]
    private List<MyClass> _list;


    [RelayCommand]
    private async Task MyCommand(MyClass val)
    {
        // never called
        await Application.Current.MainPage.DisplayAlert("Selected", val.Value, "ok");
    }


    public ViewModel()
    {
        List = [];
        for (int i = 0; i < 30; i++)
        {
            List.Add(new() { ID = i, Value = $"I_{i}" });
        }
    }
}

Finally I have made the binding on the XAML page:

<ContentPage.BindingContext>
    <local:ViewModel />
</ContentPage.BindingContext>


<ScrollView>
    <VerticalStackLayout
        Padding="30,0"
        Spacing="25">
        <CollectionView ItemsSource="{Binding List}">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <local:MyItemTemplate ApriCommand="{Binding MyCommandCommand}" />
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </VerticalStackLayout>
</ScrollView>

But the propertyChanged event nor the MyCommand are never called.

How can I solve this?

Here a repo.

Thank you.

.NET MAUI
.NET MAUI
A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
2,886 questions
0 comments No comments
{count} votes

Accepted answer
  1. Leon Lu (Shanghai Wicresoft Co,.Ltd.) 68,656 Reputation points Microsoft Vendor
    2024-04-16T02:35:34.0266667+00:00

    Hello,

    Please add  x:Name="MyContent" in your MainPage.xaml.

    <ContentPage xmlns="
    http://schemas.microsoft.com/dotnet/2021/maui"
    
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    
                 xmlns:local="clr-namespace:MauiApp5"
    
                 x:DataType="local:ViewModel"
    
                 x:Name="MyContent"
    
                 x:Class="MauiApp5.MainPage">
    

    Then change your add BindingContext and reference source like following code in Listview.

       
    <local:MyItemTemplate ApriCommand="{Binding BindingContext.MyCommandCommand,Source={x:Reference MyContent}}"/>
    

    After that, your MyCommand or propertyChanged will be invoked if you click the item in the listview.

    Best Regards,

    Leon Lu


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful