1

I'm having trouble binding values to a custom ContentView I have.

I have a ContentPage that uses a AccountStatusView that is a ContentView and has a BindableProperty. This BindableProperty is of type AccountStatus. When I try to use binding, the BindableProperty is never udpated.

Does someone know why this doesn't work?

MainPage - xaml

<Grid>
    <controls:AccountStatusView AccountStatus="{Binding AccountStatus}" />
</Grid>

MainPage - C#

public partial class MainPage : ContentPage
{
    public MainPage(ViewModel vm) {
        BindingContext = vm;
        InitializeComponent();
    }
}

ViewModel

public partial class ViewModel : ObservableObject
{
    [ObservableProperty] private AccountStatusDto _accountStatus;
    // . . .
    public async Task InitializeAsync()
    {
        AccountStatus = await _repo.GetAccountStatus();
    }
}

AccountStatusView

public partial class AccountStatusView : ContentView
{
    public static readonly BindableProperty AccountStatusProperty =
        BindableProperty.Create(nameof(AccountStatus), typeof(AccountStatusDto), typeof(AccountStatusView), propertyChanged: DoSomething);

    public static void DoSomething(BindableObject bindable, object oldvalue, object newvalue)
    {
        // do something with the new value
    }

    public AccountStatusDto AccountStatus
    {
        get => (AccountStatusDto)GetValue(AccountStatusProperty);
        set => SetValue(AccountStatusProperty, value);
    }

}

EDIT

I found this answer by ToolmakerSteve,

When making a custom component (that includes XAML), DO NOT set BindingContext = this;

And

ACCESS COMPONENT PROPERTIES VIA x:Name

Solution: Give the custom component (card) an x:Name, and make that the "Source" of those bindings:

    <VerticalStackLayout
        ...
        x:Name="me"     <-- IMPORTANT! Change name as desired.
        x:Class="DataBindingExample.Card">
        ...
        <Label Text="{Binding CardIncrement, Source={x:Reference me}}"
        ... 

And it worked perfectly

3
  • I checked the documentation and they have 'false' before callback in that example. Have you right everything? learn.microsoft.com/en-us/dotnet/maui/fundamentals/… Commented Sep 23, 2023 at 0:00
  • Yes, that false is the default value that you can give to the property. It's optional since the method signature assigns default to that parameter Commented Sep 23, 2023 at 0:06
  • If you want to set the BindingContext for a ContentView, you could set this.Content.BindingContext = new MyViewModel(); Commented Nov 1, 2023 at 6:42

1 Answer 1

0

I notice that you have found the solution, and I would like to add a few suggestions.

First, as ToolMakerSteve said that you can give the custom component (card) an x:Name, and make that the "Source" of those bindings:

  <VerticalStackLayout
        ...
        x:Name="me"     <-- IMPORTANT! Change name as desired.
        x:Class="DataBindingExample.Card">
        ...
        <Label Text="{Binding CardIncrement, Source={x:Reference me}}"
        ... 

Second, you can also add the BindingContext to the same page in a control like the VerticalStackLayout. Then, you can bind the BindableProperty to the elements in the page.

<ContentView 
             ...
             x:Name="me">

    <VerticalStackLayout BindingContext="{x:Reference me}">
        <Entry x:Name="editAnswer" Text="{Binding  BindableProperty}"> 
    </VerticalStackLayout>
</ContentView>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.