PropertyChanged.Fody自动通知属性插件
安装 PropertyChanged.Fody NuGet 包并更新 Fody NuGet 包:Install the PropertyChanged.Fody NuGet package and update the Fody NuGet package:
PM> Install-Package Fody
PM> Install-Package PropertyChanged.Fody
这是必需的,因为 NuGet 始终默认为任何依赖项的最旧、最有缺陷的版本。Install-Package Fody
添加到FodyWeavers.xml<PropertyChanged/>
<Weavers>
<PropertyChanged/>
</Weavers>
注意:实现 INotifyPropertyChanged
的所有类都将通知代码注入到属性设置器中。
在代码之前:
public class Person : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public string GivenNames { get; set; }
public string FamilyName { get; set; }
public string FullName => $"{GivenNames} {FamilyName}";
}
编译的内容:
public class Person : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
string givenNames;
public string GivenNames
{
get => givenNames;
set
{
if (value != givenNames)
{
givenNames = value;
OnPropertyChanged(InternalEventArgsCache.GivenNames);
OnPropertyChanged(InternalEventArgsCache.FullName);
}
}
}
string familyName;
public string FamilyName
{
get => familyName;
set
{
if (value != familyName)
{
familyName = value;
OnPropertyChanged(InternalEventArgsCache.FamilyName);
OnPropertyChanged(InternalEventArgsCache.FullName);
}
}
}
public string FullName => $"{GivenNames} {FamilyName}";
protected void OnPropertyChanged(PropertyChangedEventArgs eventArgs)
{
PropertyChanged?.Invoke(this, eventArgs);
}
}
internal static class InternalEventArgsCache
{
internal static PropertyChangedEventArgs FamilyName = new PropertyChangedEventArgs("FamilyName");
internal static PropertyChangedEventArgs FullName = new PropertyChangedEventArgs("FullName");
internal static PropertyChangedEventArgs GivenNames = new PropertyChangedEventArgs("GivenNames");
}
(实际注入的类型和方法名称不同)
从版本 4 开始,PropertyChanged.Fody 附带了一个 C# 代码生成器,该生成器可以通过生成 基本实现的样板直接作为源代码为您服务。INotifyPropertyChanged
只需将实现或具有属性的类标记为 和 生成器将添加必要的事件和事件调用器:INotifyPropertyChanged
[AddINotifyPropertyChangedInterface]
partial
例如,像这样的类:
public partial class Class1 : INotifyPropertyChanged
{
public int Property1 { get; set; }
public int Property2 { get; set; }
}
将通过生成器补充以下内容:
public partial class Class1
{
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}
protected virtual void OnPropertyChanged(PropertyChangedEventArgs eventArgs)
{
PropertyChanged?.Invoke(this, eventArgs);
}
}
- 仅支持类,不支持记录。
- 对于嵌套类,所有包含类也必须是分部类。
- 代码生成器仅在 SDK 样式的项目中正常工作
您可以通过项目文件中的属性配置代码生成器:
<PropertyGroup>
<PropertyChangedAnalyzerConfiguration>
<IsCodeGeneratorDisabled>false</IsCodeGeneratorDisabled>
<EventInvokerName>OnPropertyChanged</EventInvokerName>
</PropertyChangedAnalyzerConfiguration>
</PropertyGroup>
- IsCodeGeneratorDisabled:设置为以关闭代码生成器。
true
- EventInvokerName:将事件调用程序方法的名称从更改为收藏夹名称。
OnPropertyChanged
面向多个框架的 WPF 项目可能会在编译*_wpftmp.csproj
... error CS0111: Type 'SomeType' already defines a member called 'OnPropertyChanged' with the same parameter types
这可以通过将以下生成目标添加到项目中来解决:
<Target Name="RemoveDuplicateAnalyzers" BeforeTargets="CoreCompile">
<!-- see https://github.com/dotnet/wpf/pull/6680 -->
<RemoveDuplicates Inputs="@(Analyzer)">
<Output
TaskParameter="Filtered"
ItemName="FilteredAnalyzer"/>
</RemoveDuplicates>
<ItemGroup>
<Analyzer Remove="@(Analyzer)" />
<Analyzer Include="@(FilteredAnalyzer)" />
</ItemGroup>
</Target>
-
依赖属性 — 在上面的示例中,getter for 依赖于 和 的 getter 。因此,当设置了 or 时,也会为 as 提出。可以使用源属性上的
AlsoNotifyFor
属性或目标属性上的DependsOn
属性手动配置此行为。FullName
GivenName
FamilyName
GivenName
FamilyName
PropertyChanged
FullName
-
拦截通知调用
-
要获取 before/after 值,请对 / 使用以下签名:
OnPropertyChanged
On<PropertyName>Changed
public void OnPropertyChanged(string propertyName, object before, object after)
-
若要防止特定类进行通知调用注入,请使用
DoNotNotify
属性。 -
若要仅将重写范围限定为特定类,而不限于整个程序集,可以使用
FilterType
属性。这会将常规行为从“选择退出”更改为“选择加入”。例:。该字符串被解释为正则表达式,您可以使用多个筛选器。如果任何过滤器匹配,则将编织一个类。[assembly: PropertyChanged.FilterType("My.Specific.OptIn.Namespace.")]
-
可以使用
AddINotifyPropertyChangedInterfaceAttribute
属性为特定类自动实现接口。提出有关“此属性的行为不符合预期”的问题将导致 RTFM 并关闭问题。INotifyPropertyChanged
- 对于部分方法,这将通过代码生成器完成,因此在编译时可以使用实现。
-
行为是通过属性或
Weavers.xml
文件中的选项配置的。
有关详细信息,请参阅 Wiki 页面。