13
votes

I'm struggling with databinding in Xamarin Forms. Here's why, what I expect to happen from the following XAML statement:

IsVisible="{Binding Path=UserContext.IsLoggedOut}"

Is - That the property is bound to a child object of the View Model. Now either this isn't supported in Xamarin Forms or I am missing a trick.

If this is not supported in Xamarin, where it is supported in WPF, then what are we supposed to do in order to propagate nested objects? Flattening the View Model is making me write reams and reams of inelegant code.

2
How does UserContext look like?Sven-Michael Stübe
UserContext is a property of the viewModel class. UserContext object has a property called IsLoggedOutSach K
could you paste the code?Sven-Michael Stübe
Its too much code to paste in but really I don't see why inspecting the UserContext object would make much difference. I think its an issue with Xamarin.Forms not supporting nested objects in databinding, but I haven't had this confirmed to me yetSach K
It is definitely supporting nested binding. That's why I wanted to have a look at your code.Sven-Michael Stübe

2 Answers

18
votes

Nested properties are supported, like other pretty complex expression as well:

You can test it:

Xaml

<StackLayout Spacing="20">
  <StackLayout Orientation="Horizontal">
    <Label Text="Subproperties: " HorizontalOptions="FillAndExpand" FontSize="15"></Label>
    <Label Text="{Binding Item.SubItem.Text}" HorizontalOptions="FillAndExpand" FontSize="15"></Label>
  </StackLayout>
  <StackLayout Orientation="Horizontal">
    <Label Text="Indexer: " HorizontalOptions="FillAndExpand" FontSize="15"></Label>
    <Label Text="{Binding Item.Dictionary[key].Text}" HorizontalOptions="FillAndExpand" FontSize="15"></Label>
  </StackLayout>
  <StackLayout Orientation="Horizontal">
    <Label Text="Array Indexer: " HorizontalOptions="FillAndExpand" FontSize="15"></Label>
    <Label Text="{Binding Item.Array[1].Text}" HorizontalOptions="FillAndExpand" FontSize="15"></Label>
  </StackLayout>
</StackLayout>

Page

public partial class Page2 : ContentPage
{
    public ItemModel Item { get; }

    public Page2()
    {
        InitializeComponent();
        Item = new ItemModel();
        BindingContext = this;

    }
}

public class ItemModel
{
    public ItemSubModel SubItem { get; set; }
    public Dictionary<string, ItemSubModel>  Dictionary { get; set; }
    public ItemSubModel[] Array { get; set; }

    public ItemModel()
    {
        SubItem = new ItemSubModel();
        Dictionary = new Dictionary<string, ItemSubModel>
        {
            {"key", new ItemSubModel()}
        };
        Array = new [] {new ItemSubModel(), new ItemSubModel() };
    }
}

public class ItemSubModel
{
    public string Text { get; set; } = "Supported";
}

Result

enter image description here

1
votes

I'm assuming you're trying in Xaml. Try removing 'Path'.

IsVisible="{Binding UserContext.IsLoggedOut}"

However more importantly, what is your BindingContext? For the above code to work you would need the BindingContext to be set to class Foo, which has a property called UserContext, which itself has a property IsLoggedOut.

Have a look here as well