Avacay
Avacay

Reputation: 163

BindingContext with command and parameter binding

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?

Upvotes: 0

Views: 2109

Answers (2)

Dinesh
Dinesh

Reputation: 46

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

Upvotes: 1

Nikhil
Nikhil

Reputation: 3387

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>

Upvotes: 0

Related Questions