Button Command does not invoke inside CollectionView.
Both Click Event and Command should be invoked.
But button inside the CollectionView only invode click event. Whereas the button outside CollectionView invokes both Command and Click event.
Platform Target Frameworks:
Android Support Library Version:
https://drive.google.com/file/d/1ft6tytOayoUdU8ehlsJm53pHi9Tl-JIG/view?usp=sharing
The BindingContext
of a child of a CollectionView
is set to the item for that child.
So just as {Binding Name}
is looking for the name property on the Id
class, {Binding ButtonCommand}
is looking for the command on the Id
class.
To make it work you need to something like the following:
<?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:local="clr-namespace:MyApp" x:Class="MyApp.MainPage" x:Name="Page">
<ContentPage.BindingContext>
<local:MainViewModel/>
</ContentPage.BindingContext>
<StackLayout Margin="10">
<CollectionView ItemsSource="{Binding Names}">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout Spacing="0" VerticalOptions="Center" HorizontalOptions="Center">
<Button HorizontalOptions="Center" BorderWidth="2" VerticalOptions="Center" FontSize="30" Text="{Binding Name}"
TextColor="Black" Clicked="Handle_Clicked" Command="{Binding Source={x:Reference Page} Path=BindingContext.ButtonCommand}"></Button>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<Button HorizontalOptions="Center" BorderWidth="2" VerticalOptions="Center" FontSize="30" Text="ClickMe"
TextColor="Black" Clicked="Handle_Clicked" Command="{Binding ButtonCommand}"></Button>
</StackLayout>
</ContentPage>
The page has a name added: Page
and the button command binding is set explicitly to it using {x:Reference}
@GalaxiaGuy Thanks for the solution. The Button Command is invoked after applying the changes. Still this is a bug. Button inside CollectionView should be able to invoke the Command in the ViewModel.
@HobDev
GalaxiaGuy is correct - the Command is not being bound to the Button in your ItemTemplate because the BindingContext of each item in the collection is an instance of the Id class; the Id class does not have a member called ButtonCommand.
You either need to reference the parent MainViewModel instance directly (as in GalaxiaGuy's solution) or you need to add a ButtonCommand member to the Id class.
@hartez The issue is not about BindingContext. It is related to Android Runtime. Please see #5554.
If it were an Android runtime issue, then your reproduction project would work on iOS. It does not.
Here's a working version, with the ButtonCommand moved to the Id class:
MyApp_Fixed.zip
It is working on Id class without any issue. GalaxiaGuy is correct. I will reference MainViewModel instance to ButtonCommand. Thank you.
@GalaxiaGuy still on this CollectionView, I used:
<TapGestureRecognizer Command="{Binding Source={x:Reference Name=DashPage}, Path=BindingContext.TopupCommand}" CommandParameter="{Binding .}"/>
this triggers the Command but the CommandParameter is not sending the current item even though I used {Binding .}
It sends the first item instead
how can I fix this?
@nwikechisom Sounds like you might be hitting a different (more recent) bug - could you please open a new issue? Thanks.
Most helpful comment
The
BindingContext
of a child of aCollectionView
is set to the item for that child.So just as
{Binding Name}
is looking for the name property on theId
class,{Binding ButtonCommand}
is looking for the command on theId
class.To make it work you need to something like the following:
The page has a name added:
Page
and the button command binding is set explicitly to it using{x:Reference}