2 years ago

#61518

test-img

t4dohx

Xamarin - RaisePropertyChanged does not call setter of custom component's BindableProperty

I've createad a custom component MyComponent, which contains one bindable property called Title. The goal is, that when Title property changes (via binding or setter), the propertyChanged callback of BindableProperty sets new value to underlying ViewModel (MyComponentViewModel), which causes some business logic to update (this works).

This is simplified implementation of MyComponent.xaml.cs:

  [XamlCompilation(XamlCompilationOptions.Compile)]
  public partial class MyComponent {

     public MyComponentViewModel ViewModel => BindingContext as MyComponentViewModel;

     public static readonly BindableProperty TitleProperty = BindableProperty.Create(
        nameof(Title),
        typeof(string),
        typeof(MyComponent),
        "?",
        BindingMode.Default,
        propertyChanged: (b, o, n) => (b as MyComponent).ViewModel.Title = (string)n
    );
    
    public string Title {
        get => (string)GetValue(TitleProperty);
        set => SetValue(TitleProperty, value);
    }


    public MyComponent() {
        InitializeComponent();
    }
  }

The problem is, that the setter of MyComponent.Title property is not called when binding value changes (nor the propertyChanged event). When the Title is set to hardcoded value, it works fine. Let me demonstrate on a minimal example:

TestPageViewModel.cs:

  public class TestPageViewModel : Prism.Mvvm.BindableBase {
  
    
     private string _translationTest;
     public string TranslationTest {
        get => _translationTest;
        set {
            _translationTest = value;
            RaisePropertyChanged();
        }
      } 
    
      public TestPageViewModel() {
        TranslationTest = "SomeRandomText";
      }
  
  }

and a page using ViewModel above:

TestPage.xaml:

  <ContentPage ...>
  
  
    <ContentPage.BindingContext>
        <app:TestPageViewModel/>
    </ContentPage.BindingContext>
    
    <StackLayout>
    
        <!-- Binding to label text -- works: outputs `SomeRandomText` -->
        <Label Text="{Binding TranslationTest}"/>
        
        <!-- Binding this same, but to custom component -- does not work: setter not called & changed callback not fired -->
        <app:MyComponent Title="{Binding TranslationTest}"/>

        <!-- Using hardcoded value works, outputs: 'SomeHardcodedValue' -->
        <app:MyComponent Title="SomeHardcodedValue"/>
    
    </StackLayout>
  
  </ContentPage>

MyComponent.xaml

  <ContentView...>
  
  
    <ContentView.BindingContext>
        <app:MyComponentViewModel/>
    </ContentView.BindingContext>
    
    <Grid>
        <!-- some logic based on values ofapp:MyComponentViewModel -->
    </Grid>
  
  </ContentView>

What I'm doing incorrectly?

xamarin

binding

prism

0 Answers

Your Answer

Accepted video resources