Jivan Bhandari
Jivan Bhandari

Reputation: 860

Xamarin form Command Parameter object is null passing from a template view

I am implementing list view with MVVM and have tap recogniser for the label. I have a custom template for displaying the cell. I am following tutorials on binding the command. I managed to bind the command but could not figure out how to bind Command Property. My command property is always null.

My list view is like this

***** For anyone looking for the solution. Before this line I had a grid view 
like below
<Grid x:DataType="viewModels:CartViewModel"> 

************************************************

   <ListView
                            ItemsSource="{Binding CartItem.Products}"
                            HasUnevenRows="True"
                            SeparatorVisibility="None"
                            VerticalOptions="FillAndExpand"
                            CachingStrategy="RecycleElement">

                            <ListView.ItemTemplate>
                                <DataTemplate>
                                    <ViewCell>
                                        <templates:CartItemTemplate
                                            RemoveItemCommand="{Binding BindingContext.RemoveCartItemCommand, Source={x:Reference Cart}}"
                                            UpdateCartCommandParameter="{Binding .}"
                                            AddCommentCommand="{Binding BindingContext.AddCommentCommand, Source={x:Reference Cart}}"
                                            UpdateCartCommand="{Binding BindingContext.UpdateCartCommand, Source={x:Reference Cart}}"
                                            />
                                    </ViewCell>
                                </DataTemplate>
                            </ListView.ItemTemplate>
                        </ListView>

And my template is like this. Other codes are omitted.

<Label
                            Text="Update cart"
                            TextDecorations="Underline"
                            Margin="8, 0, 0, 0"
                            FontSize="12"
                            VerticalOptions="Center">
                            <Label.GestureRecognizers>
                                <TapGestureRecognizer 
                                    Command="{Binding UpdateCartCommand}"
                                    CommandParameter="{Binding UpdateCartCommandParameter}"/>
                            </Label.GestureRecognizers>
                        </Label>

In the code behind of that template I have done like this

public static readonly BindableProperty UpdateCartCommandProperty =
            BindableProperty.Create(nameof(UpdateCartCommand), typeof(ICommand), typeof(CartItemTemplate));

        public ICommand UpdateCartCommand
        {
            get => (ICommand) GetValue(UpdateCartCommandProperty);
            set => SetValue(UpdateCartCommandProperty, value);
        }

        public static BindableProperty UpdateCartCommandParameterProperty =
            BindableProperty.Create(nameof(UpdateCartCommandParameter), typeof(Product), typeof(CartItemTemplate));

        public Product UpdateCartCommandParameter
        {
            get => (Product) GetValue(UpdateCartCommandParameterProperty);
            set => SetValue(UpdateCartCommandParameterProperty, value);
        }

And finally in my MVVM code. I have implemented this.

        public ICommand UpdateCartCommand { get; }

        

        private readonly ICartService cartService;
        private readonly INavigationService navigationService;
        public CartPageViewModel(ICartService cartService, INavigationService navigationService)
        {
            this.cartService = cartService;
            this.navigationService = navigationService;
       
            UpdateCartCommand = new Command<object>(UpdateCartClicked);
           
        }

       
        private async void UpdateCartClicked(object cartItem)
        {
            await navigationService.ShowAlertAsync("Update Action", "Update cart quantity", "Ok");
        }

The problem is object cartItem is always null. What am I doing wrong here? Any idea will be helpful. Thanks

Upvotes: 1

Views: 1106

Answers (1)

Lucas Zhang
Lucas Zhang

Reputation: 18861

You invoked the line like following which is illegal .

 x:DataType="viewModels:CartPageViewModel"

Compiled bindings are currently disabled for any binding expressions that define the Source property. This is because the Source property is always set using the x:Reference markup extension, which can't be resolved at compile time.

If you want to set BindingContext in Xaml , use the following code

<ContentPage.BindingContext>
    <viewModels:xxxViewModel/>
</ContentPage.BindingContext>

Upvotes: 1

Related Questions