gpt4 book ai didi

c# - INotifyPropertyChanged 自定义属性

转载 作者:行者123 更新时间:2023-12-05 08:04:03 28 4
gpt4 key购买 nike

我喜欢对需要 INotifyPropertyChanged 接口(interface)的完整属性进行一些较少重复和浪费的编码,并进行自定义属性。

背景

今天,为了在窗口中使用具有动态更新值的 MVVM,我们需要执行以下操作:

private string _SomeProp;
public string SomeProp
{
get => _SomeProp;
set
{
_SomeProp = value;
OnPropertyChanged();
}
}

public void OnPropertyChanged([CallerMemberName] string name = null)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));

public event PropertyChangedEventHandler PropertyChanged;

建议与问题

自定义属性
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace MyProject.Models;

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class PropertyChangedAttribute : Attribute, INotifyPropertyChanged
{
public PropertyChangedAttribute([CallerMemberName] string propertyName = null)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

public event PropertyChangedEventHandler PropertyChanged;
}
将该自定义属性与属性一起使用:
[PropertyChanged]
public string SomeProp { get; set; }

所以基本上我不必为窗口中的每个字段创建完整的属性,而只需要简单的属性。

但是由于某些原因,它不起作用,并且在调试时,编译器甚至不进入自定义属性类。

更新

因此,在对该主题进行研究之后,属性 CallerMemberName 在编译器级别进行处理,这意味着,编译器查找该属性,它本身将属性/方法/等...名称传递给使用该属性的方法。

所以基本上,如果不编辑编译器代码及其行为,这样的事情是不可能做到的。

最佳答案

您可以使用实现 INotifyPropertyChanged 的公共(public)基类和为标有 PropertyChanged 的字段生成属性的源代码生成器。根据您的需要,您可能会找到一个现有的工具,或者您必须自己实现它。

一个类最终可能会这样(我为自己编写的类支持属性生成的一些属性,例如 setter 可见性):

public partial class MyCLass : NotifyPropertyChanges
{
[NotificationProperty(SetterVisibility = Visibility.Private)]
private int count;
}

生成的代码可能如下所示:

partial class MyCLass
{
[System.Runtime.CompilerServices.CompilerGenerated]
public int Count
{
[System.Runtime.CompilerServices.CompilerGenerated]
get => this.count;
[System.Runtime.CompilerServices.CompilerGenerated]
private set => SetValue(ref this.count, value, "Count");
}
}

SetValue 是这个东西的“通用”实现:

protected bool SetValue<T>(ref T field, T value, [CallerMemberName] string propertyName = "")
{
if (EqualityComparer<T>.Default.Equals(field, value))
return false;

OnPropertyChanging(new PropertyChangingEventArgs(propertyName));
field = value;
OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
return true;
}

注意:如果项目 AFAIK ( see this question ) 中有任何 .xaml 文件,源代码生成器将无法工作,因此您必须将该逻辑放在单独的项目中。

您也可以按照 Rija 的建议,将此方法与现有框架结合使用。

关于c# - INotifyPropertyChanged 自定义属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70180605/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com