CommunityToolkit / CommunityToolkit/dotnet

Add support for custom callback method in ObservableProperty

Open
#828 7 comments 4 reactions 0 assignees View on GitHub
feature request :mailbox_with_mail:
Dominant language
C#
Stars
3.8k
Forks
400
PR merge metrics
No merged PRs in 30d

Description

### Overview

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

```csharp
[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:

```csharp
[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`](https://github.com/DEVBOX10/CommunityToolkit-dotnet/blob/7b53ae23dfc6a7fb12d0fc058b89b6e948f48448/src/CommunityToolkit.Mvvm.SourceGenerators/EmbeddedResources/ObservableObject.cs#L314) method.

### Usage example

```csharp
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

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.