MVVM issue

adamgodleyadamgodley GBMember ✭✭

I have a weird issue with mvvm and custom controls. Here is some code!

MainPage.xaml

    <?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:TestXamForms"
                 x:Class="TestXamForms.MainPage">
    
        <local:TestControl Detail="{Binding Detail, Mode=TwoWay}"/>
    
    </ContentPage>

MainPage.xaml.cs

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
    }

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

        BindingContext = new MainPageVM();
    }
}

public class MainPageVM : ObservableObject
{
    public DetailModel Detail { get; set; } = new DetailModel { Name = "fish" };
}

TestControl.xaml

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="TestXamForms.TestControl">
    <ContentView.Content>
        <Label Text="{Binding Detail.Name}"/>
    </ContentView.Content>


TestControl,xaml.cs

public partial class TestControl : ContentView
{
public static readonly BindableProperty DetailProperty =
BindableProperty.Create("Detail", typeof(DetailModel), typeof(TestControl), propertyChanged: DetailPropertyChanged);

    private static void DetailPropertyChanged(BindableObject bindable, object oldValue, object newValue)
    {
        (bindable as TestControl).VM.Detail = newValue as DetailModel;
    }

    public DetailModel Detail
    {
        get => (DetailModel)GetValue(DetailProperty);
        set => SetValue(DetailProperty, value);
    }

    private TestControlVM VM
    {
        get => BindingContext as TestControlVM;
        set => BindingContext = value;
    }

    public TestControl()
    {
        InitializeComponent();
        VM = new TestControlVM();
    }
}

public class TestControlVM : ObservableObject
{
    private DetailModel _detail;

    public DetailModel Detail
    {
        get => _detail;
        set => SetProperty(ref _detail, value);
    }
}

The issue is that Detail in TestControl is not getting set, ie DetailPropertyChanged doesnt fire nor does the setter for Detail in TestControl.xaml.cs.

Have I missed something massively obviously in my bindings? It seems to be that when the BindingContext in MainPage.xaml.cs is changed in the OnAppearing method, it doesnt propagate this change down through the bindings. If this is the case (and expected behaviour), how can I overcome this? I'm hoping someone can help!

Tagged:

Posts

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    99% of the time when someone says "xyz isn't updateing", "xyz event isn't being raised" etc. its because binding context isn't what they expect. Often times the binding context is being inherited from the parent container when the developer is expecting it to just be "self".
    See if this walk through can shed some light for ya.
    https://redpillxamarin.com/2017/01/28/206-reusable-controls/

Sign In or Register to comment.