CommunityToolkit / CommunityToolkit/dotnet

Add source generation: "NotifyDataErrorInfoFor"

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

We already have the `[NotifyDataErrorInfo]` attribute, which adds source generation to validate this property.

But since we can use custom validation methods to perform multi-property validation, we should have a way to indicate that Property A influences the validation of Property B.

### API breakdown

Add an attribute, `NotifyDataErrorInfoForAttribute`, which influences the source generator to add validation of _other_ properties.

Right now, the generated setter for a property with `[NotifyDataErrorInfo]` looks like this:

```csharp
if (!global::System.Collections.Generic.EqualityComparer.Default.Equals(path, value))
{
OnPathChanging(value);
OnPathChanging(default, value);
OnPropertyChanging(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangingArgs.Path);
path = value;
ValidateProperty(value, "Path");
OnPathChanged(value);
OnPathChanged(default, value);
OnPropertyChanged(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedArgs.Path);
}
```

After the change, it would look like this:

```csharp
if (!global::System.Collections.Generic.EqualityComparer.Default.Equals(path, value))
{
OnPathChanging(value);
OnPathChanging(default, value);
OnPropertyChanging(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangingArgs.Path);
path = value;
ValidateProperty(value, "Path");
ValidateProperty(SomeOtherProperty,"SomeOtherProperty"); // <---- THIS LINE IS NEW
OnPathChanged(value);
OnPathChanged(default, value);
OnPropertyChanged(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedArgs.Path);
}
```

### Usage example

```csharp

[NotifyDataErrorInfoFor(nameof(Path))] // <--- NEW ATTRIBUTE
private bool isRequired;

[ObservableProperty]
[NotifyDataErrorInfo]
[CustomValidation(typeof(FileSystemLocationViewModel), nameof(ValidatePath))]
private string? path;

public static ValidationResult? ValidatePath(string? path, ValidationContext context)
{
var instance = (FileSystemLocationViewModel)context.ObjectInstance;
if (string.IsNullOrWhiteSpace(path))
{
if (instance.IsRequired)
return new ValidationResult("Path is required");
return ValidationResult.Success;
}
if(IsValidPath(path))
return ValidationResult.Success;
return new ValidationResult("Invalid path provided");
}

```

### Breaking change?

No

### Alternatives

Workaround (available now):

Manually implement the property

```csharp
private bool isRequired;
public bool IsRequired
{
get => this.isRequired;
set
{
if (this.SetProperty(ref this.isRequired, value))
this.ValidateProperty(this.Path, nameof(this.Path));
}
}
```

### 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.