0

I have a ViewModel, from which i construct a collection of objects. I want to be able to bind my objects on my view, while at the same time being able to use my button.

Currently, my properties are correctly bound to my labels (partnerLogo, partnerText, partnerLink). Unfortunately I'm not able to use my button command to send the command parameter that I bind.

ViewModel

Public class CarouselViewModel : INotifyPropertyChanged
{
    public CarouselViewModel()
    {
        partners = new ObservableCollection<Carousel>()
        {
            new Carousel(){partnerText = "Test123", partnerLogo = "Test123", partnerLink = "Test123" },
        };

        openWebsite = new Command<string>((key) =>
        {
            Device.OpenUri(new Uri(key));
        });
    }
    public ObservableCollection<Carousel> partners
    {
        get;
        set;
    }
    public ICommand openWebsite
    {
        private set;
        get;
    }
}

XAML:

<CarouselView ItemsSource="{Binding partners}">
    <CarouselView.ItemsLayout>
        <GridItemsLayout/>
             </CarouselView.ItemsLayout>
                 <CarouselView.ItemTemplate>
                     <DataTemplate>
                          <Frame>
                              <StackLayout>
                                  <Image Source="{Binding partnerLogo}"/>
                                  <Label Text="{Binding partnerText}"/>
                                  <Button Text="Read" Command="{Binding openWebsite}" CommandParameter="{Binding partnerLink}"/>
                             </StackLayout>
                         </Frame>
                     </DataTemplate>
            </CarouselView.ItemTemplate>
</CarouselView>

How do I access my button command, while at the same time being able to send the commandparameter?

Avacay
  • 153
  • 1
  • 13
  • Possible duplicate of [Xamarin Forms Button Command binding inside a ListView](https://stackoverflow.com/questions/40913439/xamarin-forms-button-command-binding-inside-a-listview) – Gerald Versluis Aug 20 '19 at 11:43

2 Answers2

1

For each item in the CarouselView, the binding context will be underlying data item which is bound to ItemsSource i.e., Carousel. And for CarouselView, the binding context will be your ViewModel class if you have defined it.

To resolve the issue, set the x:Name="mycaroselview" to CarouselView in the XAML and refer it's path reference to the Button command as like below code example.

<CarouselView x:Name="MyCarousel" ItemsSource="{Binding partners}">
<CarouselView.ItemsLayout>
    <GridItemsLayout/>
         </CarouselView.ItemsLayout>
             <CarouselView.ItemTemplate>
                 <DataTemplate>
                      <Frame>
                          <StackLayout>
                              <Image Source="{Binding partnerLogo}"/>
                              <Label Text="{Binding partnerText}"/>
                              <Button Text="Read" Command="{Binding BindingContext.openWebsite, Source={x:Reference Name=MyCarousel}}" CommandParameter="{Binding partnerLink}"/>
                         </StackLayout>
                     </Frame>
                 </DataTemplate>
        </CarouselView.ItemTemplate>

Make sure that you must set the binding context either to ContentPage or CarouselView.

Regards,
Dinesh

Dinesh
  • 46
  • 8
0

What you can do is, give a x:name to the content Page that you are using:-

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:MyProject;assembly= MyProject"
             x:Class="MyProject.Views.MyPage"
             x:Name="ThisPage">

And then give Source to the Command. Like this. This method will call the Command that is there in the ViewModel of the Current Page. Also, you can use a Command Parameter to know which Item has Triggered the Command.

<CarouselView ItemsSource="{Binding partners}">
    <CarouselView.ItemsLayout>
        <GridItemsLayout/>
             </CarouselView.ItemsLayout>
                 <CarouselView.ItemTemplate>
                     <DataTemplate>
                          <Frame>
                              <StackLayout>
                                  <Image Source="{Binding partnerLogo}"/>
                                  <Label Text="{Binding partnerText}"/>
                                  <Button Text="Read" Command="{Binding openWebsite, Source={x:Reference Name=ThisPage}}" CommandParameter="{Binding partnerLink}"/>
                             </StackLayout>
                         </Frame>
                     </DataTemplate>
            </CarouselView.ItemTemplate>
</CarouselView>
Nikhil
  • 3,387
  • 1
  • 8
  • 16