Neville Nazerane
Neville Nazerane

Reputation: 7019

setting up a simple component with data binding

I am trying to set up a component with data binding. This is basically a seperate content view that would have a property Item of type Item and supports binding. The following is the definition for the binding:

public static readonly BindableProperty ItemProperty
    = BindableProperty.Create(
                nameof(Item), typeof(Item), typeof(ItemComponent), null,
                defaultBindingMode: BindingMode.TwoWay,
                propertyChanged: ItemPropertyChanged);
private readonly ItemComponentViewModel vm;

static void ItemPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
    var view = (ItemComponent)bindable;
    view.Item = (Item)newValue;
}

public Item Item
{
    get => (Item)GetValue(ItemProperty);
    set
    {
        SetValue(ItemProperty, value);
        if (vm != null) vm.Data = value; // break point here
    }
}

The item doesn't seem to get bound. The commented line had a breakpoint and doesn't break. The complete source code is here: https://github.com/neville-nazerane/xamarin-component-sample

The above code can be found in the ItemComponent class. This component is called in the MainPage class.

Update

Just to explain what I am trying to simulate and why:

Why do we use MVVM in pages? While we'll have better type safety and performance by using the behind code directly, when the page's logic gets bigger, it becomes cleaner to handle it with a view model and to have a view that is simply bound to it.

Why do we have components? So that we can reuse a UI we intend to use with some functionality. If this functionality becomes complex it might need a view model for the same reason explained above. Hence, if pages need view models, I don't see why components won't need them at some point too.

This being considered this does feel like a particle requirement without easy to find examples.

Upvotes: 0

Views: 155

Answers (1)

user10608418
user10608418

Reputation:

So after looking at your example it turns out it's a bit of a complicated problem. So if my explanation is not clear, please let me know.

Basically the problem lies in these 2 code pieces:

MainPage.xaml(line 14):

<local:ItemComponent Item="{Binding Demo}" />

ItemComponent.xaml.cs (line 43):

public ItemComponent()
{
    InitializeComponent();
    vm = new ItemComponentViewModel();
    BindingContext = vm; //this breaks the functionality
}

The first part you tell it to bind to the Demo property, and as normal it looks for this property in it's BindingContext. However in the second part you override it's BindigContext and set it to a ItemComponentViewModel this ViewModel however does not have a property Demo so the {Binding Demo} does not work on this new BindingContext you've set.

Now a possible solution for your demo application would be to change MainPage.xaml to the following code:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:SampleApp"
             x:Class="SampleApp.MainPage"
             x:DataType="local:MainViewModel"
             x:Name="MyDemoPage">
    <StackLayout>
        <Label Text="Manual:" />
        <Label Text="{Binding Demo.Title}" />
        <Label Text="Component: " />
        <local:ItemComponent Item="{Binding Path=BindingContext.Demo, Source={x:Reference MyDemoPage}}" />
    </StackLayout>
</ContentPage>

Basically we now place the Demo binding outside of the BindingContext of our ItemComponent control. However if you want to use it in a ListView (if I remember correctly from your original question, this solution might not work and it's possible you'll have to drop the ItemComponentViewModel and bind directly to the properties (ListView will already make sure that the BindingContext of your ItemComponent is set to the current Item, no need to pass it around through a bindable property.

Hope this helps!

Upvotes: 1

Related Questions