Hưng Nguyễn
Hưng Nguyễn

Reputation: 57

Is there a way MVVM ObservableProperty in ObjectClass C#?

Is there a way to MVVM ObservableProperty in ObjectClass C#?

I have an ObjectClass and some properties inside

public class FontsVip
{
    private static FontsVip obj;
    public static FontsVip Obj
    {
        get { if (obj == null) obj = new FontsVip(); return obj; }
        set => obj = value;
    }
    public string yellow;
}

I have a MAUI xaml page containing a control Binding color attribute to Model.

<Label Text="{Binding Eye}" VerticalOptions="Center"
    FontFamily="FontsVip"
    FontSize="21"
    TextColor="{Binding Eyecolor}">

My MVVM Model is as follows:

public partial class Model: ObservableObject
{
    [ObservableProperty]
    [NotifyPropertyChangedFor(nameof(Eyecolor))]
    private FontsVip fsv = FontsVip.Obj;

    [ObservableProperty]
    private string Eyecolor;

    [RelayCommand]
    public void changeColor()
    {
        AppTheme currenttheme = (AppTheme)Application.Current.RequestedTheme;
        if (currenttheme is AppTheme.Dark)
        {
            Fsv.yellow = "#ff00ff";
            //Eyecolor = Fsv.yellow;
        }
    }
    ...
 }

My problem is that on Model it is not possible to observe changes based on changed properties of Class FontsVip and update it to XAML view.

If I uncomment

//Eyecolor = Fsv.yellow

it works perfectly. But this is actually not based on Observable.

Upvotes: 0

Views: 129

Answers (1)

mpasdanis
mpasdanis

Reputation: 289

To solve this issue, you can modify the FontsVip class to implement the INotifyPropertyChanged. You may have your view automatically update when a property changes by implementing this interface, which lets you raise events anytime a property changes.

  • Add a property Yellow the encapsulates the field yellow.
  • OnPropertyChanged method is used to raise the PropertyChanged event.
public class FontsVip : INotifyPropertyChanged
{
    private static FontsVip obj;
    public static FontsVip Obj
    {
        get { if (obj == null) obj = new FontsVip(); return obj; }
        set => obj = value;
    }

    private string yellow;
    public string Yellow
    {
        get => yellow;
        set
        {
            if (yellow != value)
            {
                yellow = value;
                OnPropertyChanged(nameof(Yellow));
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Changes in FontsVip.Yellow must be detected by your ViewModel, and it must update Eyecolor appropriately. Given that FontsVip is a singleton, you might configure this logic in an initialization function or the constructor of the ViewModel: :

public partial class Model : ObservableObject
{
    public Model()
    {
        FontsVip.Obj.PropertyChanged += FontsVip_PropertyChanged;
    }

    private void FontsVip_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == nameof(FontsVip.Yellow))
        {
            Eyecolor = FontsVip.Obj.Yellow;
        }
    }

    [ObservableProperty]
    private string eyecolor;

    [RelayCommand]
    public void ChangeColor()
    {
        AppTheme currentTheme = (AppTheme)Application.Current.RequestedTheme;
        if (currentTheme == AppTheme.Dark)
        {
            FontsVip.Obj.Yellow = "#ff00ff";
        }
    }

    protected override void OnDisposing()
    {
        FontsVip.Obj.PropertyChanged -= FontsVip_PropertyChanged;
        base.OnDisposing();
    }
}

Upvotes: 2

Related Questions