Nanou Ponette
Nanou Ponette

Reputation: 1402

Xamarin Forms Prism Pass a property via CommandParameter

I don't know how I can pass a single property via CommandParameter to my Command function in the ViewModel.

Now I pass the whole object (CategoryListItem) but I only need the value from the Id property. How can I achieve this?

Class:

public class CategoryListItem
{
    public int Id { get; set; }
    public int Order { get; set; }

    public string Name { get; set; }
}

ViewModel:

public ObservableRangeCollection<CategoryListItem> Listing
    {
        get => _listing;
        set => SetProperty(ref _listing, value);
    }

OnItemTappedCommand = new DelegateCommand<CategoryListItem>(OnItemTapped);

private async void OnItemTapped(CategoryListItem obj)
    {
        await _navigationService.GoBackAsync(new NavigationParameters
        {
            { "CategoryId", obj.Id }
        });
    }

XAML:

<ListView
        ItemsSource="{ Binding Listing }"
        HasUnevenRows="false"
        CachingStrategy="RecycleElement"
        SeparatorColor="{ DynamicResource AccentColor }">

        <ListView.Behaviors>
            <b:EventToCommandBehavior 
                EventName="ItemTapped"
                Command="{ Binding OnItemTappedCommand }"
                CommandParameter="???"
                EventArgsConverter="{ StaticResource ItemTappedEventArgsConverter }">
            </b:EventToCommandBehavior>
        </ListView.Behaviors>

        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <Label 
                        Text="{ Binding Name }"
                        VerticalTextAlignment="Center"
                        HorizontalTextAlignment="Center"
                        FontSize="16" />
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>

    </ListView>

Converter:

public class ItemTappedEventArgsConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (!(value is ItemTappedEventArgs itemTappedEventArgs))
        {
            throw new ArgumentException("error");
        }

        return itemTappedEventArgs.Item;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Any ideas are welcome! Nothing worked for me.

Upvotes: 0

Views: 1162

Answers (2)

djrpascu
djrpascu

Reputation: 410

I don't think you can bind to the tapped record from there. You might be able to do something in your ItemTemplate like create a behavior on the view cell and pass the property from there.

If you want to avoid the converter you could use "EventArgsParameterPath" instead:

           <b:EventToCommandBehavior 
            EventName="ItemTapped"
            Command="{Binding OnItemTappedCommand}"
            EventArgsParameterPath="Item">
        </b:EventToCommandBehavior>

Set it to "Item" and it will still send the entire CategoryListItem.

See documentation here: https://prismlibrary.github.io/docs/xamarin-forms/EventToCommandBehavior.html

Upvotes: 0

Leo Zhu
Leo Zhu

Reputation: 15021

i think you don't need to use CommandParameter,you could return the CategoryListItem.Id directly in your ItemTappedEventArgsConverter:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    if (!(value is ItemTappedEventArgs itemTappedEventArgs))
    {
        throw new ArgumentException("error");
    }

    return ((CategoryListItem)itemTappedEventArgs.Item).Id;
}

then in you ViewModel :

OnItemTappedCommand = new DelegateCommand<int>(OnItemTapped);

private async void OnItemTapped(int id)
{
  // here you could get the Id property
}

Upvotes: 0

Related Questions