C# 重构属性ChangedEventHandler
在我的UI代码中,我有许多具有相同基本框架的类:C# 重构属性ChangedEventHandler,c#,.net,wpf,C#,.net,Wpf,在我的UI代码中,我有许多具有相同基本框架的类: 派生自INotifyPropertyChanged 包含以下代码: void NotifyPropertyChanged(String info) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(info)); } } public event PropertyChangedEvent
- 派生自INotifyPropertyChanged
- 包含以下代码:
void NotifyPropertyChanged(String info) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(info)); } } public event PropertyChangedEventHandler PropertyChanged;
这似乎是一个完美的机会,可以将其纳入一个类并从中派生,而不是INotifyPropertyChanged,但遗憾的是,C#不支持多重继承,因此它实际上不起作用。关于如何重构此类代码,您有什么想法吗?也许您可以使用以下方法:
class A1 : INotifyPropertyChanged
{
private string _myProperty;
private static Expression<Func<A1, string>> myProperty = _ => _.MyProperty;
public string MyProperty
{
get { return _myProperty; }
set
{
_myProperty = value;
InvokePropertyChanged(myProperty);
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void InvokePropertyChanged<T>(Expression<Func<A1, T>> property)
{
PropertyChangedEventHandler Handler = PropertyChanged;
if (Handler != null)
{
MemberExpression expression = (MemberExpression)property.Body;
Handler(this, new PropertyChangedEventArgs(expression.Member.Name));
}
}
}
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
A1类:INotifyPropertyChanged
{
私有字符串_myProperty;
private static Expression您不能将此代码放入您的超类的超类中吗
- 反对
- 您的具体NotifyPropertyChanged类是4行永远不会更改的代码。创建一个代码段!通常的做法是让基类实现INotifyPropertyChanged,如下所示:
class A1 : INotifyPropertyChanged
{
private string _myProperty;
private static Expression<Func<A1, string>> myProperty = _ => _.MyProperty;
public string MyProperty
{
get { return _myProperty; }
set
{
_myProperty = value;
InvokePropertyChanged(myProperty);
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void InvokePropertyChanged<T>(Expression<Func<A1, T>> property)
{
PropertyChangedEventHandler Handler = PropertyChanged;
if (Handler != null)
{
MemberExpression expression = (MemberExpression)property.Body;
Handler(this, new PropertyChangedEventArgs(expression.Member.Name));
}
}
}
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
然后,您的类将从此类派生,当您希望通知属性值的更改时,可以调用OnPropertyChanged:
public class PersonViewModel : ViewModelBase
{
public PersonViewModel(Person person)
{
this.person = person;
}
public string Name
{
get
{
return this.person.Name;
}
set
{
this.person.Name = value;
OnPropertyChanged("Name");
}
}
}
这可能是一个小帮助,但您可以使用params关键字,以便一次可以更改多个属性
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertiesChanged(params string[] Properties)
{
if (PropertyChanged != null)
foreach (string property in Properties)
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
这将减少您在将来通知属性更改时使用的行数。因此,您可以使用:
通知财产变更(“foo”、“bar”)
而不是:
通知财产变更(“foo”);
NotifyPropertyChanged(“酒吧”)
否则,我同意Anders的建议,将其移到继承树上可能是最好的。让topparent不要从Notify classNatrium继承,这会弄脏很多与此无关的类:(你能再解释一下吗?Sergey,这是解决依赖魔术弦的问题的许多好方法之一。我不确定这是OP问的问题,though@Anders:我的意思是,也许你不必从某个类派生,你可以很容易地手工完成它?如果不是,还有一些额外的方法:1.代码生成2.反射3。PostSharpPropFu似乎并没有解决问题,它仍然有事件+方法的复制。但它确实有一些帮助。@Anders:是的!实际上这段代码只会促进进一步的重构。你对PostSharp有什么看法?是的,我想我必须这样做。感谢MVVM的参考,很高兴知道人们知道这一点我只是对那些关于WPF(编程WPF)的书感到困惑没有提到这样的事情,或者说WPF没有一些NoTIFYPyTyTryC改类,因为它必须很快地出现,导致了丑陋的重复代码。但是,当我写到NATRIUM时,它真的是一个相当丑陋的解决方案,因为中间的类被格式化成他们不应该关心的东西。使用OOP可以做到的最好;-)Hmm.,你的意思是,中间的类被美化成他们不应该关心的东西?在你的项目中这些中产阶级负责什么?中间的帮助类可能只是有一些共同的功能。也许中间的助手类可以被推到一个单独的静态类中,一个扩展方法,或者一个帮助对象,作为一个依赖项提供给你的UI类,尽管你可能需要添加线程安全性:ValueNoTIFYPrimTyType(String Fipe){var处理程序=PrimTyType;(handler!=null){handler(this,newpropertychangedeventargs(info));}