Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Add flag to NotifyPropertyChangedFor and NotifyCanExecuteChangedFor that allows notification on sub property changes

Abierto
#1,168 1 comentario 1 reacción 0 asignados Ver en GitHub

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

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

feature request :mailbox_with_mail:
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

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de CommunityToolkit/dotnet

Todos los issues de CommunityToolkit/dotnet

Issues similares

Más issues de C#

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.