WPF开发中PropertyChanged.Fody的使用

现在基本上每一个项目都会使用PropertyChanged.Fody,用了以后,代码确实简洁清爽了很多。

安装

Install-Package PropertyChanged.Fody

继承INotifyPropertyChanged接口

安装了PropertyChanged.Fody以后,默认会为带INotifyPropertyChanged接口的类里面的属性都加上变更通知功能。

public class Person : INotifyPropertyChanged
{
   [AlsoNotifyFor("FullName")]
   public string GivenName { get; set; }

   [AlsoNotifyFor("FullName")]
   public string FamilyName { get; set; }

   public event PropertyChangedEventHandler PropertyChanged;

   public string FullName { get; set; }
}

因为我平常开发的时候基本上都会使用Prism,所以一般我会把类定义下继承Prism的BindableBase类,如下:

public class Person : BindableBase
{
   [AlsoNotifyFor("FullName")]
   public string GivenName { get; set; }

   [AlsoNotifyFor("FullName")]
   public string FamilyName { get; set; }

public string FullName { get; set; }
}

因为BindableBase类会实现INotifyPropertyChanged接口。

ImplementPropertyChanged

也通过给没有INotifyPropertyChanged接口的类,增加ImplementPropertyChanged附加属性来实现通知的功能。但好像不推荐,官方推荐用上面的方式。

[ImplementPropertyChanged]
public class Person 
{
    public string Name { get; set; }
}

DoNotNotify

不希望通知的属性可以加上[DoNotNotify]的附加属性。

public class Person : INotifyPropertyChanged
{
   public string GivenName { get; set; }
   [DoNotNotify]
   public string FamilyName { get; set; }
   public event PropertyChangedEventHandler PropertyChanged;
}

AlsoNotifyFor

如果想要某个属性变化了以后,同时通知其它属性,可以添加AlsoNotifyFor附加属性。

public class Person : INotifyPropertyChanged
{
   [AlsoNotifyFor("FullName")]
   public string GivenName { get; set; }

   [AlsoNotifyFor("FullName")]
   public string FamilyName { get; set; }

   public event PropertyChangedEventHandler PropertyChanged;

   public string FullName { get; set; }
}

在GivenName或FamilyName变化时,会同时也通知FullName的变化。

DependsOn

如果属性之间有联动的,也可以通过添加DependsOn附加属性来实现同步通知的功能。

public class Person : INotifyPropertyChanged
{
    public string GivenName { get; set; }

    public string FamilyName { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;

    [DependsOn("GivenName","FamilyName")]
    public string FullName { get; set; }
}

这样只要GivenName和FamilyName属性发生变化了,也会通知界面FullName属性变更了。

当然也可以使用下面的nameof的方式。

public class Person : INotifyPropertyChanged
{
    public string GivenName { get; set; }

    public string FamilyName { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;

    [DependsOn(nameof(GivenName), nameof(FamilyName))]
    public string FullName { get; set; }
}

IsChanged

如果类里面添加了IsChanged属性,但只要类里的属性有变化,IsChanged会自动被设为true。

public class Person: INotifyPropertyChanged
{
    public string FullName { get; set; }
    public bool IsChanged { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;
}

DoNotSetChanged

如果希望某个属性变化的时候,不修改IsChanged的值,可以添加DoNotSetChanged的附加属性。

public class Person: INotifyPropertyChanged
{
    public string GivenName { get; set; }

    public string FamilyName { get; set; }

    [DoNotSetChanged]
    public string FullName { get; set; }
    public bool IsChanged { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;
}

上面的代码,GivenName和FamilyName属性发生变化时,IsChanged的值会变为true。FullName属性变化时,IsChanged的值不会变。

DoNotCheckEquality

默认情况下,变化响应会先检查是否相等,如果相等,则不会进行通知。

如果需要不管相等不相等,都进行变更通知。则可以加上DoNotCheckEquality附加属性。

public class Person: INotifyPropertyChanged
{
   [DoNotCheckEquality]
   public string FullName { get; set; }
   public bool IsChanged { get; set; }

   public event PropertyChangedEventHandler PropertyChanged;
}

这样,在给FullName赋值时,无论是否和之前的值相等,都会进行通知。

常见问题

1、编译时提示【Fody: The package reference for PropertyChanged.Fody does not contain PrivateAssets='All'】的错误

这个报错是指在使用Fody和PropertyChanged.Fody库时,包引用中缺少`PrivateAssets='All'`的设置。为了解决这个问题,可以按照以下步骤进行操作:

1. 打开你的项目文件(例如.csproj文件)。

2. 找到对应的`<PackageReference>`元素,它指向PropertyChanged.Fody库。

3. 在该元素内部添加`<PrivateAssets>all</PrivateAssets>`,确保设置正确。

   <PackageReference Include="PropertyChanged.Fody">
     <PrivateAssets>all</PrivateAssets>
   </PackageReference>

4. 保存并关闭项目文件。

5. 重新构建项目,检查报错是否解决。

 通过添加`<PrivateAssets>all</PrivateAssets>`设置,你告诉MSBuild在构建项目时不包含这个包引用的任何私有资产。这可以防止这个包被传递到依赖项中,并解决了`PrivateAssets='All'`的缺失导致的报错。

如果问题仍然存在,可能需要检查Fody和PropertyChanged.Fody库的版本兼容性,并确保它们与你的项目和其他依赖项兼容。

参考网址

https://github.com/Fody/PropertyChanged

https://www.cnblogs.com/cqgis/p/6360231.html
https://www.cnblogs.com/cqgis/p/6360302.html

posted @ 2023-07-13 15:06  wzwyc  阅读(1181)  评论(1编辑  收藏  举报