Home > Software design >  .net Maui binding values multiple levels deep
.net Maui binding values multiple levels deep

Time:09-29

How can I Pass a Binding from a Page to a View?

I have this Page(Xaml)

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:views="clr-namespace:DataBindingTests.Views"
             xmlns:model="clr-namespace:DataBindingTests.ViewModels"
             x:Class="DataBindingTests.Pages.CoolePage"
             Title="CoolePage"
             x:DataType="model:CoolesModel">
    <VerticalStackLayout>
        <Label Text="{Binding YourName}"></Label>
        <views:MainView YourName="{Binding YourName}"></views:MainView>
        <Button Command="{Binding ChangeNameCommand}"></Button>
    </VerticalStackLayout>
</ContentPage>

And its CodeBehind:

using DataBindingTests.ViewModels;

namespace DataBindingTests.Pages;

public partial class CoolePage : ContentPage
{
    public CoolePage()
    {
        this.BindingContext = new CoolesModel();
        InitializeComponent();
    }
}

If I pass a String into my MainView it works and all events are fired. When I use the binding it doesn't. In this simple test, the app should display two times the same name, but only the Label of the ContentPage has the YourName property printed

<views:MainView YourName="Lars"></views:MainView> <-- Works

<views:MainView YourName="{Binding YourName}"></views:MainView> <-- doesn't work

This is the Xaml of the MainView

<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:views="clr-namespace:DataBindingTests.Views"
             x:Class="DataBindingTests.Views.MainView">
    <VerticalStackLayout>
        <Label Text="{Binding YourName}"
            VerticalOptions="Center" 
            HorizontalOptions="Center" />
    </VerticalStackLayout>
</ContentView>

This is the CodeBehind of the MainView

namespace DataBindingTests.Views;

public partial class MainView : ContentView
{
    public String YourName
    {
        get
        {
            String value = (String)GetValue(MainView.YourNameProperty);
            return value;
        }
        set
        {
            SetValue(MainView.YourNameProperty, value);
        }
    }

    public static readonly BindableProperty YourNameProperty = BindableProperty.Create(nameof(YourName)
    , typeof(String)
    , typeof(MainView), defaultBindingMode:BindingMode.TwoWay, propertyChanged: OnYourNameChanged);

    static void OnYourNameChanged(BindableObject bindable, object oldValue, object newValue)
    {
        Console.WriteLine(newValue);
    }

    public MainView()
    {
        this.BindingContext = this; // Ignore ParentContext
        InitializeComponent();
    }
}

CodePudding user response:

In this simple test, the app should display two times the same name, but only the Label of the ContentPage has the YourName property printed

You're overwriting your binding context half way through for some reason, and the context your page binding resolves (the normal way of using it, the parent context) is different than what you actually see on the screen (which is your this.BindingContext = this). And you never set your second context's property.

CodePudding user response:

You can just remove code this.BindingContext = this; from the constructor of MainView.xaml.cs:

 public MainView()
    {
        //this.BindingContext = this;
        InitializeComponent();
    }
  • Related