是否有办法避免在 Xamarin 中每个方法的 setter 中调用 NotifyChanged ?

Moh*_*mel 1 c# mvvm xamarin xamarin.forms

这个问题说明了一切。使用 Xamarin 时会出现这种模式:

public string Property
        {
            get
            {
                return this.propertyField;
            }

            set
            {
                if (value != this.propertyField)
                {
                    this.propertyField = value;
                    NotifyPropertyChanged();
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)

看来我必须为我拥有的每处房产都这样做。有什么办法可以避免重蹈覆辙吗?

Ger*_*uis 5

有!

最简单的方法是安装PropertyChanged.Fody包 ( Nuget )。

安装后,您的项目根目录中应该有一个 weavers.xml 文件。打开它,确保它包含以下内容:

<?xml version="1.0" encoding="utf-8" ?>
<Weavers>
  <PropertyChanged/>
</Weavers>
Run Code Online (Sandbox Code Playgroud)

现在,您只需INotifyPropertyChanged在要实现通知功能的类上添加接口即可!对于所有公共属性,样板代码是在编译时生成的。

来自自述文件:

你写这个

public class Person : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public string GivenNames { get; set; }
    public string FamilyName { get; set; }
    public string FullName => $"{GivenNames} {FamilyName}";
}
Run Code Online (Sandbox Code Playgroud)

生成/编译的内容是这样的

public class Person : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    string givenNames;
    public string GivenNames
    {
        get => givenNames;
        set
        {
            if (value != givenNames)
            {
                givenNames = value;
                OnPropertyChanged("GivenNames");
                OnPropertyChanged("FullName");
            }
        }
    }

    string familyName;
    public string FamilyName
    {
        get => familyName;
        set 
        {
            if (value != familyName)
            {
                familyName = value;
                OnPropertyChanged("FamilyName");
                OnPropertyChanged("FullName");
            }
        }
    }

    public string FullName => $"{GivenNames} {FamilyName}";

    public virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,这里发生了一些很酷的事情。检测并解释属性之间的依赖性。还支持快照属性符号。

此外,还有一些属性可用于控制如何处理属性。一些:

  • [DoNotNotify]从生成通知代码中排除属性
  • [AlsoNotifyFor(nameof(OtherProperty)]或 [DependsOn(nameof(OtherProperty)] 使用此属性,您还可以在属性之间创建依赖关系。

示例可以在Github 上的 wiki上找到