So I have a collectionview and inside of that I have an expander with 3 buttons. The problem is that once I touch one of these 3 buttons they don't do nothing even if they're binded to commands.
Here's how it looks like:
Here's the code:
<CollectionView HorizontalScrollBarVisibility="Never"
Margin="0,5,20,15"
ItemsSource="{Binding Books}"
VerticalOptions="StartAndExpand"
ItemsLayout="HorizontalList"
HeightRequest="210">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout Margin="8,0">
<xct:Expander>
<xct:Expander.Header>
<Grid RowDefinitions="*,auto">
<PanCake:PancakeView Grid.Row="0" Margin="0,0,20,0">
<ffimageloading:CachedImage Source="{Binding Cover}" HeightRequest="200" WidthRequest="145" Aspect="Fill"/>
</PanCake:PancakeView>
<Label Text="{Binding Title}" FontSize="14" Grid.Row="1" HorizontalOptions="Start" FontFamily="Inter" WidthRequest="145" LineBreakMode="TailTruncation" MaxLines="2" FontAttributes="Bold" TextColor="Black"/>
</Grid>
</xct:Expander.Header>
<xct:Expander.ContentTemplate>
<DataTemplate>
<StackLayout Orientation="Horizontal" Margin="0,10,0,0">
<ImageButton Source="trash_24.png" BackgroundColor="Transparent" HorizontalOptions="Start" Command="{Binding RemoveBookFromCollection}" CommandParameter="{Binding .}" Margin="0,0,0,0">
</ImageButton>
<ImageButton Source="cross_24.png" BackgroundColor="Transparent" Command="{Binding SetBookAvailability}" CommandParameter="{Binding .}" WidthRequest="24" HeightRequest="24" HorizontalOptions="Start" Margin="10,0,0,0">
</ImageButton>
<ImageButton Source="check_24.png" BackgroundColor="Transparent" Command="{Binding SetBookAvailability}" CommandParameter="{Binding .}" HorizontalOptions="Start" Margin="10,0,0,0">
</ImageButton>
</StackLayout>
</DataTemplate>
</xct:Expander.ContentTemplate>
</xct:Expander>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
The DataTemplate
has a different BindingContext
than the rest of the Page. The DataTemplate
inherits its BindingContext
from each book instance in the Books
collection. You need to use a relative binding in your command binding expression, e.g.:
Command="{Binding RemoveBookFromCollection, Source={RelativeSource AncestorType={x:Type viewModel:YourViewModel}}"
This will become apparent in the IDE, if you provide the x:DataType
to the DataTemplate.
You also don't need the ContentTemplate for the body of the Expander, since you're directly providing the content yourself.
Since you didn't show the ViewModel, I will use a generic name, so you'll have to adapt it to your needs to make it work:
<CollectionView
ItemsSource="{Binding Books}">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="model:Book">
<xct:Expander>
<xct:Expander.Header>
<Grid RowDefinitions="*,auto">
<PanCake:PancakeView Grid.Row="0" Margin="0,0,20,0">
<ffimageloading:CachedImage Source="{Binding Cover}" HeightRequest="200" WidthRequest="145" Aspect="Fill"/>
</PanCake:PancakeView>
<Label Text="{Binding Title}" FontSize="14" Grid.Row="1" HorizontalOptions="Start" FontFamily="Inter" WidthRequest="145" LineBreakMode="TailTruncation" MaxLines="2" FontAttributes="Bold" TextColor="Black"/>
</Grid>
</xct:Expander.Header>
<StackLayout Orientation="Horizontal" Margin="0,10,0,0">
<ImageButton
Source="trash_24.png"
Command="{Binding RemoveBookFromCollection, Source={RelativeSource AncestorType={x:Type viewModel:YourViewModel}}"
CommandParameter="{Binding .}">
</ImageButton>
<!-- etc ... -->
</StackLayout>
</xct:Expander>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
The viewModel:YourViewModel
should of course be replaced with your actual namespace and ViewModel. The namespace needs to be included in the XAML header of your page as an XML namespace (xmlns
) and ideally also provide the x:DataType
to the Page in order to use compiled bindings which also helps the IDE in pointing out binding issues to you and it will produce compiler errors for faulty binding expressions, e.g.:
<ContentPage
xmlns:viewModel="YourProject.SomeFolderWhereTheViewModelExists"
x:DataType="viewModel:YourViewModel" />
Using the compiled bindings and the x:DataType
attribute is entirely optional, though, but will help with binding expressions.
or similar.