4

I have the following Contentpage.content, where I set certain binding context.

<StackLayout>
    <local:Post />  
    <local:Comments />
</StackLayout>

In Post.xaml.cs (ContentView), I've tried to get the binding context of the ContentPage this way but it doesn't work.

BindingContext = (PostViewModel)Parent.BindingContext;

How can I get the binding context of the ContentPage if I'm standing in a ContentView?

Fede Berco
  • 71
  • 1
  • 1
  • 8

2 Answers2

11

By the time your constructor is called, the BindingContext might not be initialised yet.

So, you should wait for the BindingContext being changed to perform operations on it.

I think the answer is OnBindingContextChanged event. https://developer.xamarin.com/api/member/Xamarin.Forms.View.OnBindingContextChanged()

Little sample:

        protected override void OnBindingContextChanged ()
        {
            base.OnBindingContextChanged ();

            //BindingContext should not be null at this point
            // and you may add your code here.
        }

Note: If you have a ContentView inside a ContentPage, unless explicitly set by another Control (like when using an ItemTemplate for a ListView) or by your code, the BindingContext of the ContentView is the same as the ContentPage.

So, it shouldn't be necessary to call "Parent".

Let me know if more clarification is needed.

Rodrigo Elias
  • 783
  • 7
  • 18
  • thx, good answer, additionally I have found that setting the bindingcontext of the parent in the constructor rather than onappearring also helps performance when taking this approach – Mike Mar 21 '17 at 12:43
  • hey Rodrigo, nice on but how do we get the binding inside listview datatemplate ? I tried using "{Binding Path=BindingContext.SomeValue, Source={x:Reference Name=ContentViewName}} But this doesnt work if it iin listview – Emil May 11 '18 at 20:37
  • @batmaci - maybe TemplateBinding, e.g. `{TemplateBinding Parent.BindingContext.YourField}` as mentioned in [Xamarin forums- Binding within a ControlTemplate](https://forums.xamarin.com/discussion/68683/binding-within-a-controltemplate). – ToolmakerSteve May 18 '18 at 08:23
  • @ToolmakerSteve problem is with the 2nd level contenview. I saw somewhere else on xamarin forums that if I use contentview inside contentview, it doesnt work. moving into first contentview or directly in the contentpage works fine – Emil May 18 '18 at 10:02
0

The BindingContext of the ContentView is usually also the BindingContext of the ContentPage since it is passed down from the parent.

So you should not even need to set ContentView.BindingContext if you already set the parent ContentPage.BindingContext.

If I am missing something, please let me know.

hvaughan3
  • 10,955
  • 5
  • 56
  • 76
  • If I set for example `var ViewModel = (PostViewModel)BindingContext;`, the ViewModel is Null. So it doesn't work. @hvaughan3 – Fede Berco Jun 16 '16 at 19:39
  • 1
    @FedeBerco Right because when the `ContentView` is initialized, the parent `ContentPage.BindingContext` is probably `null` still. You should not need to worry about setting the `BindingContext` in the `ContentView` at all and should only need to bind your controls, since the controls will get filled in with values once the `BindingContext` of the `ContentPage` finally does get set. – hvaughan3 Jun 16 '16 at 19:43
  • I understand what you say, but I need to use the ViewModel of the BindingContext in the constructor of the ContentView to show and hide items according to certain conditionals. I've tried to set the BindingContext before the InitializeComponent(); but it doesn't work yet. Was I clear? @hvaughan3 – Fede Berco Jun 16 '16 at 20:00
  • @FedeBerco That sounds like a job for either a [Trigger](https://developer.xamarin.com/guides/xamarin-forms/working-with/triggers/) (but you will have a very hard time using it if you are not using XAML in `ContentView`) or even a [Behavior](https://developer.xamarin.com/guides/xamarin-forms/behaviors/creating/). Would those do what you need? An alternative would just be to bind your control's `IsVisible` property to a property in your ViewModel to control the conditional if that makes sense in your situation – hvaughan3 Jun 16 '16 at 20:13
  • Thats not always the case if you use Contentview within a DataTemplate of for example CarouselView – Emil Aug 28 '20 at 23:40
  • @batmaci In those cases you can always add an `x:Name` to your `ContentPage` element and then use `x:Reference MyContentPage` with a Path of `BindingContext.SomeProperty` for your binding. Then you are able to reference the binding context outside of your view. See something like this: https://stackoverflow.com/a/52919182/3850012 – hvaughan3 Aug 29 '20 at 01:20