Search code examples
maui

BindableProperty setter never called when property set


I'm working on a custom control in .net MAUI. This is what I have:

public partical class CalendarView : ContentView, INotifyPropertyChanged
{
     public static readonly BindableProperty TempProperty = BindableProperty.Create(
            propertyName: nameof(Temp),
            returnType: typeof(int),
            declaringType: typeof(CalendarView),
            defaultValue: 0);

    public int Temp
    {
        get { return (int)GetValue(TempProperty); }
        set
        {
            SetValue(TempProperty, value);
            RaisePropertyChanged("Temp");
        }
    }
}

This is how the related xaml looks like:

<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MyApp.Controls.CalendarView"
             x:Name="this">

    <Label IsVisible="False" Text="{Binding Temp, Source={x:Reference this}, Mode=TwoWay}"/>

</ContentView>

This is how I'm using my control in my application pages:

<controls:CalendarView Temp="{Binding SelectedYear, Mode=TwoWay}"/>

In this case, everything works as expected. But if I remove the Label from my control related xaml, the property Temp setter is never called.

What I'm trying to achieve?

I would like to perform some action in my control everytime the property Temp setter is called. But this setter is only called when there is a view in the related xaml consuming this property.

I'm wondering how can I achieve what I'm looking for without having a view on the related xaml consuming Temp.


Solution

  • I would like to perform some action in my control everytime the property Temp setter is called. But this setter is only called when there is a view in the related xaml consuming this property.

    I'm wondering how can I achieve what I'm looking for without having a view on the related xaml consuming Temp.

    You can add parameter: propertyChanged of BindableProperty.Create Method, it run when the value will change:

    public partial class CalendarView : ContentView
    {
        public static readonly BindableProperty TempProperty = BindableProperty.Create(
                propertyName: nameof(Temp),
                returnType: typeof(int),
                declaringType: typeof(CalendarView),
                defaultValue: 0,
                propertyChanged: RaisePropertyChanged);
     
        private static void RaisePropertyChanged(BindableObject bindable, object oldValue, object newValue)
        {
            Console.WriteLine("do something");
        }
     
        public int Temp
        {
            get { return (int)GetValue(TempProperty); }
            set
            {
                SetValue(TempProperty, value);
            }
        }
        public CalendarView()
        {
            InitializeComponent();
        }
    }
    

    I tested it, and RaisePropertyChanged can be called when there is no view in the related xaml consuming this property.

    In addition, about the setter not called you can also refer to this case: Binding to a usercontrol's DependencyProperty is not calling the setter.