CommunityToolkit / CommunityToolkit/dotnet

NewPropertyChangedEvent on ObservableObject

Open
#801 0 comments 0 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

I want to get the old value and the new value in the event

### API breakdown

```csharp
namespace CommunityToolkit.Mvvm.ComponentModel;
public abstract class ObservableObject
{
protected bool SetProperty(
[NotNullIfNotNull(nameof(newValue))] ref T field,
T newValue,
[CallerMemberName] string? propertyName = null
)
{
if (EqualityComparer.Default.Equals(field, newValue))
{
return false;
}

OnPropertyChanging(propertyName);

var oldValue = field;
if (AnotherPropertyChanging is not null)
AnotherPropertyChanging?.Invoke(this, new(propertyName, oldValue, newValue));

field = newValue;

OnPropertyChanged(propertyName);

if (AnotherPropertyChanged is not null)
AnotherPropertyChanged?.Invoke(this, new(propertyName, oldValue, newValue));

return true;
}

public event AnotherPropertyChangingEventHandler? AnotherPropertyChanging;
public event AnotherPropertyChangedEventHandler? AnotherPropertyChanged;
}

public delegate void AnotherPropertyChangingEventHandler(
object sender,
AnotherPropertyChangingEventArgs e
);
public delegate void AnotherPropertyChangedEventHandler(
object sender,
AnotherPropertyChangedEventArgs e
);

public class AnotherPropertyChangingEventArgs : PropertyChangingEventArgs
{
public object? OldValue { get; }

public object? NewValue { get; }

public AnotherPropertyChangingEventArgs(
string? propertyName,
object? oldValue,
object? newValue
)
: base(propertyName)
{
OldValue = oldValue;
NewValue = newValue;
}
}

public class AnotherPropertyChangedEventArgs : PropertyChangedEventArgs
{
public object? OldValue { get; }

public object? NewValue { get; }

public AnotherPropertyChangedEventArgs(string? propertyName, object? oldValue, object? newValue)
: base(propertyName)
{
OldValue = oldValue;
NewValue = newValue;
}
}
```

### Usage example

```csharp
public partial class MainWindowViewModel : ObservableObject
{
AnotherViewModel anotherViewModel = new();

[ObservableProperty]
private int _oldValue = 0;

[ObservableProperty]
private int _newValue = 0;

public MainWindowViewModel()
{
anotherViewModel.AnotherPropertyChanged += (s, e) =>
{
if (e.PropertyName == nameof(AnotherViewModel .Value))
{
OldValue = e.OldValue;
NewValue = e.NewValue;
}
};
}
}

public partial class AnotherViewModel : ObservableObject
{
[ObservableProperty]
private int _value = 0;
}
```

### Breaking change?

No

### Alternatives

Currently I'm using reflection to get the old value, but that's a very bad.
```csharp
protected override void OnPropertyChanging(PropertyChangingEventArgs e)
{
base.OnPropertyChanging(e);
if (AnotherPropertyChanged is not null)
{
_oldValue = this.GetType().GetProperty(propertyName).GetValue(this);
}
}
```

### Additional context

_No response_

### Help us help you

Yes, I'd like to be assigned to work on this item

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.