1
votes

I have been trying all the "Qs that may have your answer" 3 days later, still no joy.

I have a XAML Page that holds a ListView of products and their details, using binding to a model called RackProducts as you can see:

<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="PapillonWine.PapillonRackCatalogPage" 
             xmlns:local="clr-namespace:PapillonWine;assembly=PapillonWine" 
             xmlns:artina="clr-namespace:UXDivers.Artina.Shared;assembly=UXDivers.Artina.Shared"
             xmlns:customContentView="clr-namespace:PapillonWine.NavBars"
             Title="{ artina:Translate PageTitleProductsCatalog }"
             BackgroundColor="{ DynamicResource MainWrapperBackgroundColor }"
             x:Name="CatalogItemPage">

    <ContentPage.Content>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="70" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>

            <customContentView:CustomNavigationBar Grid.Row="0" x:Name="NavigationBarView" BackgroundColor="Transparent"/>

            <ListView
            x:Name="PapillonRackItems"    
            Grid.Row="1" 
            ItemsSource="{ Binding RackProducts }"
            HasUnevenRows="True"
            ItemSelected="OnItemSelected">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <local:PapillonCatalogItemTemplate />
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </Grid>
    </ContentPage.Content>
</ContentPage>

Each product is displayed using the PapillonCatalogItemTemplate which holds four buttons (to view a carousel of product images, to add to cart, to view dimensions and lastly to share the product). This PapillonCatalogItemTemplate is as follows:

<?xml version="1.0" encoding="utf-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="PapillonWine.PapillonCatalogItemTemplate" 
             xmlns:local="clr-namespace:PapillonWine;assembly=PapillonWine" 
             xmlns:artina="clr-namespace:UXDivers.Artina.Shared;assembly=UXDivers.Artina.Shared"
             xmlns:customContentView="clr-namespace:PapillonWine.NavBars"
             xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms" 
             xmlns:fftransformations="clr-namespace:FFImageLoading.Transformations;assembly=FFImageLoading.Transformations"
             Padding="10" BackgroundColor="{ DynamicResource MainWrapperBackgroundColor }" 
             x:Name="CatalogItemTemplate">

    <!-- FAVORITE ICON -->


    <Grid>
        <!-- COLUMN DEFS -->
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <!-- ROW DEFS -->
        <Grid.RowDefinitions>
            <RowDefinition Height="0.45*" />
            <RowDefinition><RowDefinition.Height><OnIdiom x:TypeArguments="GridLength" Phone="200" Tablet="400" /></RowDefinition.Height></RowDefinition>
        </Grid.RowDefinitions>

      <StackLayout Grid.Column="0" Grid.Row="0" Spacing="5" HorizontalOptions="FillAndExpand" WidthRequest="1000" >

      <!-- PRODUCT NAME -->
        <Label Text="{ Binding Name }" />                            

       <!-- DESCRIPTION -->
         <Label Text="{Binding Description}" />


        <!-- BUTTONS -->
      <StackLayout x:Name="buttonstack" Orientation="Horizontal" >

          <!-- SHOW IMAGES -->
          <artina:Button
            x:Name="ImageCarousel"
            Text="{ x:Static local:FontAwesomeWeb511Font.CameraRetro }"
            Style="{StaticResource FontIcon}"
            BindingContext="{Binding Source={x:Reference CatalogItemTemplate}, Path=BindingContext}" 
            Command="{Binding OnClickViewImageCarousel}" 
            CommandParameter="{Binding Source={x:Reference buttonstack}, Path=BindingContext}" >

          <!-- SHOW CART -->
          <artina:Button
            Text="{ x:Static local:FontAwesomeWeb511Font.cartplus }"
            Style="{StaticResource FontIcon}"
            Clicked="OnBuyItemSelected">
          </artina:Button>

          <!-- SHOW DIMENSIONS -->
          <artina:Button
            Text="{ x:Static local:FontAwesomeWeb511Font.RulerCombined }"
            Style="{StaticResource FontIcon}"
            Clicked="OnDimensionsSelected" >

          <!-- SHOW IMAGES -->
          <artina:Button
            Text="{ x:Static local:FontAwesomeFont.Share }"
            Style="{StaticResource FontIcon}"
            Clicked="OnShareSelected" >

        </StackLayout>                
        </StackLayout>     

                    <ffimageloading:CachedImage
                        Grid.Column="0" Grid.Row="1"
                        Source="{ Binding Image }" />       
        </Grid>
</ContentView>

If I click the ffloading image at the bottom of the template item, the OnItemSelected button fires, and I get a nice new view page with a picture of the product that I selected and all its item details... bully! The code it fires is as follows:

public async void OnItemSelected(object sender, SelectedItemChangedEventArgs e)
        {
            var selectedItem = ((ListView)sender).SelectedItem;

            var page = new PapillonRackItemViewPage(((RackProduct)selectedItem).Id);

            await Navigation.PushModalAsync(page);
        }

However... if I try to fire one of the buttons within the item template (for example the one directly beneath "SHOW IMAGES", nothing happens. I have left the Commmand, CommandParameter and Binding arguments in that first button but I'm not sure they're correct. I have tried ICommand route, TapGestureRecognizer route, and tried most similar posts, and I really need help on this one. How do I pass the same binding context as in the ListView and its "RackProducts" binding, through button items within a list view? Any chance of a much needed helping hand? Thanks!

1
Is the problem that you can't get an event/command to fire for the individual buttons, or that you don't know how to access the context for the item in the handler?Jason
@Jason hi, sorry if I wasn't clear. I can fire an event handler, from both the image and the button inside the listview item, it is just that the image binding will pass me the item selected and all its details (var selectedItem = ((ListView)sender).SelectedItem) but the button inside the listview item gives me nothing. Hope I'm clearer. Shout if not. Cheers for looking...Mark
CommandParameter="{Binding .}"Jason
@Jason changed "CommandParameter="{Binding Source={x:Reference buttonstack}, Path=BindingContext}" " for CommandParameter="{Binding .}"... the button isn't even firing now.Mark
I notice you have a BindingContext assigned for just that button, that won't work with my suggestion. Try using it with just a Clicked handler insteadJason

1 Answers

6
votes

in your XAML

Clicked="OnClickViewImageCarousel" CommandParameter="{Binding .}"

then in the code behind

protected void OnClickViewImageCarousel(object sender, EventArgs e) 
{
  var selectedItem = (RackProduct)((Button)sender).CommandParameter; 
}