Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for custom callback method in ObservableProperty #828

Open
hailstorm75 opened this issue Jan 16, 2024 · 2 comments
Open

Add support for custom callback method in ObservableProperty #828

hailstorm75 opened this issue Jan 16, 2024 · 2 comments
Labels
feature request 📬 A request for new changes to improve functionality

Comments

@hailstorm75
Copy link

hailstorm75 commented Jan 16, 2024

Overview

Assume that you are developing an observable model of a setting that contains a set of fields, decorated by the ObservableProperty attribute:

[ObservableObject]
public sealed partial class MyModel
{
  [ObservableProperty] private string _myField = string.Empty;
}

Assuming that this is a setting, other parts of the application might need to know when this setting is modified, i.e., it becomes dirty.
This is easily achieved using Messaging; however, it would require the developer to manually convert this field to a property with a backing field, defeating the purpose of the ObservableProperty attribute:

[ObservableObject]
public sealed partial class MyModel
{
  private string _myField = string.Empty;

  public string MyField
  {
    get => _myField;
    set
    {
      if (SetProperty(ref _myField, value))
        WeakReferenceMessenger.Default.Send(new SettingsChangedMessage(value, nameof(MyModel)));
    }
  }
}

I believe an additional attribute that allows the developer to specify a callback method to be executed once the property is changed or even retrieved would be beneficial.

API breakdown

I'm not familiar enough with IIncrementalGenerator and the current CommunityToolkit.MVVM implementation to provide a useful API breakdown.

However, I believe the generated code could utilize the SetPropertyAndNotifyOnCompletion method.

Usage example

public sealed partial class MyObservableClass : ObservableObject
{
  [ObservableProperty(CallbackSet = nameof(CustomSetCallback))] private string m_userEmail;

  private void CustomSetCallback(object oldValue, object newValue)
  {
    // TODO
  }
}

Breaking change?

I'm not sure

Alternatives

Currently, I've reserved to implement a custom generator using ISourceGenerator that finds an ObservablePropertyEx attribute to generate the necessary code with callback support.

Additional context

No response

Help us help you

No, just wanted to propose this

@hailstorm75 hailstorm75 added the feature request 📬 A request for new changes to improve functionality label Jan 16, 2024
@ol65
Copy link

ol65 commented Jan 21, 2024

I would like to have this feature too! Sometimes I have to reload some properties when another property has changed. A callback method within the setter would be great for this.

@giacomo-cc
Copy link

+1 on this
I thinks this could be helpful also for those cases where we want to trigger the same callback for multiple properties OnChanged events.

Right now we have to do something like this:

[ObservableProperty]
private bool _propertyA;
partial void OnPropertyAChanged(bool value) => DoStuff();

[ObservableProperty]
private bool _propertyB;
partial void OnPropertyBChanged(bool value) => DoStuff();

[ObservableProperty]
private bool _propertyC;
partial void OnPropertyCChanged(bool value) => DoStuff();

private void DoStuff()
{
    // do stuff here
}

With the proposed feature we could simplify, like this:

[ObservableProperty(CallbackSet = nameof(DoStuff))]
private bool _propertyA;

[ObservableProperty(CallbackSet = nameof(DoStuff))]
private bool _propertyB;

[ObservableProperty(CallbackSet = nameof(DoStuff))]
private bool _propertyC;

private void DoStuff()
{
    // do stuff here
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request 📬 A request for new changes to improve functionality
Projects
None yet
Development

No branches or pull requests

3 participants