0

I'm trying to let each view in a CarouselView have the same BindingContext object as the parent ContentPage. I've tried the following which doesn't seem to work. MainPage.xaml is the page that is initialized at runtime. It holds a CarouselView with four ContentViews holding "pages" of functionality I can swipe back and forth between from the MainPage.

MainPage.xaml:

...
<CarouselView Grid.Row="1" Grid.ColumnSpan="4"
              Position="{Binding CarouselPosition}"
              HorizontalScrollBarVisibility="Never">
    <CarouselView.ItemsSource>
        <x:Array Type="{x:Type ContentView}">
            <local:HomeView></local:HomeView>
            <local:NewsView></local:NewsView>
            <local:ChartsView></local:ChartsView>
            <local:SettingsView></local:SettingsView>
        </x:Array>
    </CarouselView.ItemsSource>
    <CarouselView.ItemTemplate>
        <DataTemplate>
            <ContentView Content="{Binding .}" BindingContext="{Binding BindingContext, Source={x:Reference mainPage}}"/>
        </DataTemplate>
    </CarouselView.ItemTemplate>
</CarouselView>
...

Basically, I want to be able to set the BindingContext for each of these ContentViews to be the same as the parent's. I've also read that the ContentViews should be able to inherit the BindingContext sometimes, but it doesn't seem to be happening in this situation.

Thanks.

supernova
  • 88
  • 7
  • the BindingContext will be whatever the "selected" element of ItemsSource is. In your example you shouldn't need to set the BindingContext – Jason Mar 01 '20 at 22:49
  • Is there anything I have to do in the ContentView codebehinds to make that work? The bindings aren't working as of now. @Jason – supernova Mar 01 '20 at 23:36
  • If you want to set the bindingcontext for four pages in ItemsSource, you coudl try to set it in each page code instead of ItemTemplate. – Wendy Zang - MSFT Mar 13 '20 at 09:17

1 Answers1

0

This is because this kind of control doesn't inherit its BindingContext from its parent but it has its own BindingContext set to the item of the collection binded to the ItemsSource which makes sense.

Let's say you want to display a collection of User. The DataTemplate will be the user interface of a User. You want to display some properties of a User, not your ViewModel.

If you want to bind to something exposed in the ViewModel and not the User, you have to bind the BindingContext of your element with either a RelativeSource or by targeting an element by its x:Name.

Exemple : to bind a button inside your DataTemplate to a command exposed in your ViewModel (not in User), you need to do that :

<Button
    Text="Try me"
    Command="{Binding
        Path=BindingContext.MyViewModelCommand,
        Source={x:Reference xNameOfParentOutsideDataTemplateOrThePage}" />

To make it easier to understand, what it does is : I want to bind to something on the control called xNameOfParentOutsideDataTemplateOrThePage (x:Name="xNameOfParentOutsideDataTemplateOrThePage"). On this control, I want to a property of its BindingContext (most of the time, your view model).

Instead of x:Reference, you can also use a RelativeSource binding.

Nk54
  • 751
  • 7
  • 15