2016-07-22 61 views
2

新的世界粮食计划署(MVVM),这似乎是处理用户变化的典型方式:WPF OnPropertyChanged重复码

private bool someProperty= false; 
    public bool SomeProperty 
    { 
     get { return someProperty; } 
     set 
     { 
      if (someProperty!= value) 
      { 
       someProperty= value; 
       OnPropertyChanged(nameof(SomeProperty)); 


      } 
     } 
    } 

对于一个大而复杂的屏幕,这就需要编辑的字段很多,而且处理马上(不是最后点击一个按钮时),这会导致大量的重复代码。似乎很难保持,如果你有50个或更多的属性呢?有没有更好的方法来做到这一点?

回答

0

这里的救命技巧是使用PropertyChanged.Fody,它在编译时将INotifyPropertyChanged代码注入到属性中,并执行一些其他更聪明的操作。

+0

看起来不错。我将如何使用它为特定属性添加一些自定义内容?意思是除了OnPropertyChanged()我想执行一些其他特定的代码。 –

+0

我想我在这里找到了自己的答案:https://github.com/Fody/PropertyChanged/wiki/On_PropertyName_Changed –

0

您可以使用此方法:

private void OnPropertyChanged([CallerMemberName] string propertyName = null) 
{ 
    var handler = PropertyChanged; 
    if (handler != null) 
    { 
     handler(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

而且在每个属性使用这样的:

private bool someProperty= false; 
    public bool SomeProperty 
    { 
     get { return someProperty; } 
     set 
     { 
      if (someProperty!= value) 
      { 
       someProperty= value; 
       OnPropertyChanged(); 
      } 
     } 
    } 
+0

我的问题是所有7-10行代码,我宁愿每个属性只有1或2 :) –

+0

@Keith只需使用'PropertyChanged.Fody'工具。 – mechanic

0

我用我所有的ViewModels带有此功能的基类是:

protected void RaisePropertyChanged(string propertyName) 
{ 
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
} 

protected bool SetValue<T>(ref T backingField, T newValue, [CallerMemberName] string propertyName = "") 
{ 
    if (EqualityComparer<T>.Default.Equals(backingField, newValue)) 
    { 
     return false; 
    } 
    backingField = newValue; 
    RaisePropertyChanged(propertyName); 
    return true; 
} 

然后,您可以从任何子类以这种方式使用它:

private string _firstName; 

public string FirstName 
{ 
    get { return _firstName; } 
    set { SetValue(ref _firstName, value); } 
} 

SetValue将返回true如果新值比以前的值不同,false如果是一样的,只是在情况下,你需要链更复杂的制定者任何进一步的行动。