Ala*_*ain 20 c# wpf events .net-3.5
是否存在类似于INotifyPropertyChanged的接口,其中事件args包含要更改的属性的旧值,或者我是否必须扩展该接口以创建一个?
例如:
public String ProcessDescription
{
get { return _ProcessDescription; }
set
{
if( value != ProcessDescription )
{
String oldValue = _ProcessDescription;
_ProcessDescription = value;
InvokePropertyChanged("ProcessDescription", oldvalue);
}
}
}
InvokePropertyChanged(String PropertyName, OldValue)
{
this.PropertyChanged( new ExtendedPropertyChangedEventArgs(PropertyName, OldValue) );
}
Run Code Online (Sandbox Code Playgroud)
我也会讨论类似PropertyChanging的事件,它提供这些信息,无论它是否支持e.Cancel.
Ala*_*ain 37
如答案所示,我必须实施自己的解决方案.为了别人的利益,我在这里介绍了它:
扩展PropertyChanged事件
此活动专门设计为向后兼容旧的propertyChanged事件.它可以与调用者使用简单的PropertyChangedEventArgs互换使用.当然,在这种情况下,事件处理程序有责任检查传递的PropertyChangedEventArgs是否可以向下转换为PropertyChangedExtendedEventArgs,如果他们想要使用它.如果他们感兴趣的是PropertyName属性,则不需要向下转换.
public class PropertyChangedExtendedEventArgs<T> : PropertyChangedEventArgs
{
public virtual T OldValue { get; private set; }
public virtual T NewValue { get; private set; }
public PropertyChangedExtendedEventArgs(string propertyName, T oldValue, T newValue)
: base(propertyName)
{
OldValue = oldValue;
NewValue = newValue;
}
}
Run Code Online (Sandbox Code Playgroud)
扩展PropertyChanged接口
如果程序员想要创建一个强制通知属性包含旧值和新值的事件,则只需要实现以下接口:
// Summary: Notifies clients that a property value is changing, but includes extended event infomation
/* The following NotifyPropertyChanged Interface is employed when you wish to enforce the inclusion of old and
* new values. (Users must provide PropertyChangedExtendedEventArgs, PropertyChangedEventArgs are disallowed.) */
public interface INotifyPropertyChangedExtended<T>
{
event PropertyChangedExtendedEventHandler<T> PropertyChanged;
}
public delegate void PropertyChangedExtendedEventHandler<T>(object sender, PropertyChangedExtendedEventArgs<T> e);
Run Code Online (Sandbox Code Playgroud)
例1
用户现在可以指定一个更高级的NotifyPropertyChanged
方法,允许属性设置器传递其旧值:
public String testString
{
get { return testString; }
set
{
String temp = testString;
testValue2 = value;
NotifyPropertyChanged("TestString", temp, value);
}
}
Run Code Online (Sandbox Code Playgroud)
您的新NotifyPropertyChanged
方法如下所示:
protected void NotifyPropertyChanged<T>(string propertyName, T oldvalue, T newvalue)
{
OnPropertyChanged(this, new PropertyChangedExtendedEventArgs<T>(propertyName, oldvalue, newvalue));
}
Run Code Online (Sandbox Code Playgroud)
和OnPropertyChanged
以往一样:
public virtual void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(sender, e);
}
Run Code Online (Sandbox Code Playgroud)
例2
或者,如果您更喜欢使用lambda表达式并完全取消硬编码的属性名称字符串,则可以使用以下命令:
public String TestString
{
get { return testString; }
private set { SetNotifyingProperty(() => TestString, ref testString, value); }
}
Run Code Online (Sandbox Code Playgroud)
以下魔术支持以下内容:
protected void SetNotifyingProperty<T>(Expression<Func<T>> expression, ref T field, T value)
{
if (field == null || !field.Equals(value))
{
T oldValue = field;
field = value;
OnPropertyChanged(this, new PropertyChangedExtendedEventArgs<T>(GetPropertyName(expression), oldValue, value));
}
}
protected string GetPropertyName<T>(Expression<Func<T>> expression)
{
MemberExpression memberExpression = (MemberExpression)expression.Body;
return memberExpression.Member.Name;
}
Run Code Online (Sandbox Code Playgroud)
性能
如果需要考虑性能,请参阅此问题:在没有魔术字符串的情况下实现NotifyPropertyChanged.
总之,开销很小.添加旧值并切换到扩展事件大约减少了15%,仍然允许每秒大约一百万个属性通知,并且切换到lambda表达式是5倍减速,允许每个大约十万个属性通知第二.这些数字远远不能在任何UI驱动的应用程序中形成瓶颈.
归档时间: |
|
查看次数: |
15032 次 |
最近记录: |