gpt4 book ai didi

c# - 更好的 PropertyChanged 和 PropertyChanging 事件处理

转载 作者:可可西里 更新时间:2023-11-01 08:04:11 26 4
gpt4 key购买 nike

我正在为我们的应用程序实现观察者模式 - 目前正在使用 RX 框架。

我目前有一个看起来像这样的例子:

Observable.FromEventPattern<PropertyChangedEventArgs>(Instance.Address, "PropertyChanged")
.Where(e => e.EventArgs.PropertyName == "City")
.ObserveOn(Scheduler.ThreadPool)
.Subscribe(search => OnNewSearch(search.EventArgs));

(我有一个类似的“PropertyChanging”)

EventArgs 给我的东西不多。我想要的是 EventArgs 的扩展,它使我能够查看以前的值和新值,以及在“变化的”监听器中标记事件的能力,这样变化实际上不会持续存在。如何才能做到这一点?谢谢。

最佳答案

我认为这取决于您如何实现 INotifyPropertyChanging 和 INotifyPropertyChanged 接口(interface)。

遗憾的是,PropertyChangingEventArgs 和 PropertyChangedEventArgs 类不提供属性的前后值或取消更改的能力,但您可以派生自己的事件参数类来提供该功能。

首先,定义以下事件参数类。请注意,这些派生自 PropertyChangingEventArgs 类和 PropertyChangedEventArgs 类。这允许我们将这些对象作为参数传递给 PropertyChangingEventHandler 和 PropertyChangedEventHandler 委托(delegate)。

class PropertyChangingCancelEventArgs : PropertyChangingEventArgs
{
public bool Cancel { get; set; }

public PropertyChangingCancelEventArgs(string propertyName)
: base(propertyName)
{
}
}

class PropertyChangingCancelEventArgs<T> : PropertyChangingCancelEventArgs
{
public T OriginalValue { get; private set; }

public T NewValue { get; private set; }

public PropertyChangingCancelEventArgs(string propertyName, T originalValue, T newValue)
: base(propertyName)
{
this.OriginalValue = originalValue;
this.NewValue = newValue;
}
}

class PropertyChangedEventArgs<T> : PropertyChangedEventArgs
{
public T PreviousValue { get; private set; }

public T CurrentValue { get; private set; }

public PropertyChangedEventArgs(string propertyName, T previousValue, T currentValue)
: base(propertyName)
{
this.PreviousValue = previousValue;
this.CurrentValue = currentValue;
}
}

接下来,您需要在 INotifyPropertyChanging 和 INotifyPropertyChanged 接口(interface)的实现中使用这些类。一个实现示例如下:

class Example : INotifyPropertyChanging, INotifyPropertyChanged
{
public event PropertyChangingEventHandler PropertyChanging;

public event PropertyChangedEventHandler PropertyChanged;

protected bool OnPropertyChanging<T>(string propertyName, T originalValue, T newValue)
{
var handler = this.PropertyChanging;
if (handler != null)
{
var args = new PropertyChangingCancelEventArgs<T>(propertyName, originalValue, newValue);
handler(this, args);
return !args.Cancel;
}
return true;
}

protected void OnPropertyChanged<T>(string propertyName, T previousValue, T currentValue)
{
var handler = this.PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs<T>(propertyName, previousValue, currentValue));
}

int _ExampleValue;

public int ExampleValue
{
get { return _ExampleValue; }
set
{
if (_ExampleValue != value)
{
if (this.OnPropertyChanging("ExampleValue", _ExampleValue, value))
{
var previousValue = _ExampleValue;
_ExampleValue = value;
this.OnPropertyChanged("ExampleValue", previousValue, value);
}
}
}
}
}

请注意,PropertyChanging 和 PropertyChanged 事件的事件处理程序仍需要将原始 PropertyChangingEventArgs 类和 PropertyChangedEventArgs 类作为参数,而不是更具体的版本。但是,您将能够将事件参数对象转换为更具体的类型,以便访问新属性。

下面是这些事件的事件处理程序示例:

class Program
{
static void Main(string[] args)
{
var exampleObject = new Example();

exampleObject.PropertyChanging += new PropertyChangingEventHandler(exampleObject_PropertyChanging);
exampleObject.PropertyChanged += new PropertyChangedEventHandler(exampleObject_PropertyChanged);

exampleObject.ExampleValue = 123;
exampleObject.ExampleValue = 100;
}

static void exampleObject_PropertyChanging(object sender, PropertyChangingEventArgs e)
{
if (e.PropertyName == "ExampleValue")
{
int originalValue = ((PropertyChangingCancelEventArgs<int>)e).OriginalValue;
int newValue = ((PropertyChangingCancelEventArgs<int>)e).NewValue;

// do not allow the property to be changed if the new value is less than the original value
if(newValue < originalValue)
((PropertyChangingCancelEventArgs)e).Cancel = true;
}

}

static void exampleObject_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "ExampleValue")
{
int previousValue = ((PropertyChangedEventArgs<int>)e).PreviousValue;
int currentValue = ((PropertyChangedEventArgs<int>)e).CurrentValue;
}
}
}

关于c# - 更好的 PropertyChanged 和 PropertyChanging 事件处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8577207/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com