Add flag to NotifyPropertyChangedFor and NotifyCanExecuteChangedFor that allows notification on sub property changes
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Aptitud para principiantes
- 35/100
- Tipo de issue
- Nueva funcionalidad
- Claridad
- Bastante claro
- Estado de actividad
- Tranquilo
- Stack tecnológico
- csharp
- Área
- developer-experience
Línea de trabajo
Empieza con NotifyPropertyChangedForAttribute y NotifyCanExecuteChangedForAttribute, y después sigue los puntos de entrada de los generadores de código fuente de ObservableProperty y RelayCommand. Compara el setter generado solicitado y el controlador de subpropiedades con la salida generada actual. Se considera terminado cuando haya una API decidida y notificaciones funcionales para los cambios en subpropiedades, incluido el caso de RelayCommand.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Overview
I frequently have a property that depends on the sub-property of another property in my viewmodels. The most common case for me is the IsRunning property of AsyncRelayCommand, but I've run into many other examples.
I'd like some sort of way to indicate that another property or command has changed when a sub-property has changed. Ideally this could be extended to [RelayCommand] declarations as well so that when the automatically generated command starts or stops, other properties are notified.
API breakdown
Preferably we could add a boolean property called NotifyOnSubPropertyChanged to NotifyPropertyChangedForAttribute and NotifyCanExecuteChangedForAttribute that opts into this behavior when set to true.
Usage example
I would use it like this:
public partial class TestViewModel : ObservableObject
{
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(FormattedProp1), NotifyOnSubPropertyChanged = true)]
[NotifyCanExecuteChangedFor(nameof(Command1Command), NotifyOnSubPropertyChanged = true)]
public partial SubViewModel SubViewModel { get; private set; } = new();
public string FormattedProp1 => "_" + SubViewModel.Prop1 + "_";
[RelayCommand(CanExecute = nameof(CanDoThing1))]
[property: NotifyCanExecuteChangedFor(nameof(DoThing2Command), NotifyOnSubPropertyChanged = true)]
private Task DoThing1() => Task.CompletedTask;
private bool CanDoThing1() => SubViewModel.Prop1 is not null;
[RelayCommand(CanExecute = nameof(CanDoThing2))]
private void DoThing2() { }
private bool CanDoThing2() => !DoThing1Command.IsRunning;
}
public partial class SubViewModel : ObservableObject
{
[ObservableProperty]
public partial string Prop1 { get; set; }
}
I think the generated code would look something like this for the SubViewModel property:
/// <inheritdoc/>
[global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "8.4.0.0")]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public partial global::WpfTests.SubViewModel SubViewModel
{
get => field;
private set
{
if (!global::System.Collections.Generic.EqualityComparer<global::WpfTests.SubViewModel>.Default.Equals(field, value))
{
OnSubViewModelChanging(value);
OnSubViewModelChanging(default, value);
OnPropertyChanging(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangingArgs.SubViewModel);
OnPropertyChanging(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangingArgs.FormattedProp1);
(field as INotifyPropertyChanged)?.PropertyChanged -= OnSubPropertyChanged;
field = value;
(field as INotifyPropertyChanged)?.PropertyChanged += OnSubPropertyChanged;
OnSubViewModelChanged(value);
OnSubViewModelChanged(default, value);
OnPropertyChanged(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedArgs.SubViewModel);
OnPropertyChanged(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedArgs.FormattedProp1);
DoThing1Command.NotifyCanExecuteChanged();
}
void OnSubPropertyChanged(object? sender, PropertyChangedEventArgs args)
{
OnPropertyChanged(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedArgs.FormattedProp1);
DoThing1Command.NotifyCanExecuteChanged();
}
}
Note that the handler for detecting sub-property changes is removed and added in the parent property setter, and the handler itself is a local function of the setter that is populated based on the property names provided.
I'm not sure how it would integrate into the RelayCommandAttribute, but it would be really nice to have for that for asynchronous commands.
Breaking change?
No
Alternatives
Right now all of this has to be configured in the constructor or initializer, and greatly hinders some of the benefits of the source generators.
An alternative might be to have a new attribute, but I think this is a little cleaner.
Additional context
No response
Help us help you
Yes, but only if others can assist
- Lenguaje dominante
- C#
- Estrellas
- 3.8k
- Forks
- 401
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de CommunityToolkit/dotnet
-
bug :bug:
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
CommunityToolkit/dotnet#1206 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
CommunityToolkit/dotnet#1186 ·
-
bug :bug:
Dificultad 1/5 Menos de una hora Aptitud para principiantes 68/100
CommunityToolkit/dotnet#648 ·
-
bug :bug:
Dificultad 3/5 1-2 días Aptitud para principiantes 68/100
CommunityToolkit/dotnet#1215 ·
-
feature request :mailbox_with_mail:
Dificultad 5/5 Más de una semana Aptitud para principiantes 45/100
CommunityToolkit/dotnet#1214 ·
Todos los issues de CommunityToolkit/dotnet
Issues similares
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
ClickHouse/clickhouse-cs#639 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 92/100
ifpebj-ti/controle-acesso-veiculos#377 ·
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
Los mantenedores suelen responder en 1 día
-
Money ExploitsAbiertoS: Untriaged
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
project-wayfarer/wayfarer-14#1628 ·
Los mantenedores suelen responder en 3 días
-
:watch: Not Triaged dotnet-target-version
Dificultad 1/5 Menos de una hora Aptitud para principiantes 85/100
Los mantenedores suelen responder en 1 día