我正在使用INotifyPropertyChanged在我的WinForm应用程序中传播更改。
在这里,我有代码在UNIX纪元整数时间戳和System DateTime对象之间进行转换。它接收一个ConvertEventArgs对象,该对象包含一个对象值和要转换为的DesiredType。
使用INotifyPropertyChanged并向Control添加动态绑定时,您可以提供在ConvertEventArg对象中提供DesiredType的处理程序。
我有一个我称之为NotifyBase的基类,它包含这个静态函数:
public class NotifyBase {
public static void UpdateDataBindings(string propertyName
, Control ctl
, object bindingSource
, string bindingPropertyName
, Action<object, ConvertEventArgs> formatFunc = null
, Action<object, ConvertEventArgs> parseFunc = null
, bool clearBefore = true
, bool formattingEnabled = true) {
var b = new Binding(propertyName, bindingSource, bindingPropertyName, formattingEnabled, DataSourceUpdateMode.OnPropertyChanged);
if (formatFunc != null) b.Format += (sender, args) => formatFunc(sender,args);
if (parseFunc != null) b.Format += (sender, args) => parseFunc(sender,args);
if(clearBefore) ctl.DataBindings.Clear();
ctl.DataBindings.Add(b)
基类也实现了这个:
public event PropertyChangedEventHandler PropertyChanged;
protected void SetPropertyField<T>(ref T field, T newValue,
[System.Runtime.CompilerServices.CallerMemberName] string propertyName = "") {
if (EqualityComparer<T>.Default.Equals(field, newValue)) return;
field = newValue;
// Ignoring online conjecture about the need to keep a reference to the event property
// before invoking it.
// 1. this is a single threaded app.
// 2. documentation clearly says that event handlers should merely be checked for being null.
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
然后我初始化我的数据绑定。以下是Winform DateTimePicker的示例。
NotifyBase.UpdateDataBindings("Value", TimePickerBox, Config, nameof(Config.UnitTimestamp)
, (o, args) => { NotifyBase.PropertyTypeChange(args, ReportingTimeZoneInfo); }
, (o, args) => { NotifyBase.PropertyTypeChange(args, ReportingTimeZoneInfo); });
PropertyTypeChange函数实质上接受ConvertEventArg并为其提供所需的类型:
Type u = Nullable.GetUnderlyingType(carg.DesiredType);
if (carg.DesiredType == typeof(DateTime) || u == typeof(DateTime)) {
if (u == null) {
if (carg.Value is int) {
carg.Value = epoch.AddSeconds((int) carg.Value);
}
else if (carg.Value is DateTime) carg.Value = carg.Value; // do not throw if type is already the expected type.
else throw new ArgumentOutOfRangeException("Value type conversion to DateTime is not supported.");
} else {
DateTime tp;
if (carg.Value is int) {
tp = epoch.AddSeconds((int) carg.Value);
}
else if (carg.Value is DateTime) tp = (DateTime) carg.Value; // do not throw if type is already the expected type.
else throw new ArgumentOutOfRangeException("Value type conversion to DateTime is not supported.");
carg.Value = tp.MakeNullable<DateTime>();
}
}
无论如何,想用“是”做类型对应更优雅。 但是,正如我的监视窗口所示,即使它清楚地显示对象是整数,它也不会解析为int:
我的问题:
我认为is
表达式等同于object.GetType() == typeof(int)
。 这不是真的吗?
似乎没有,我想更好地理解这是真实的条件。
无论如何,在没有可靠的答案的情况下,我将继续前进,只是让一切都使用GetType()。
使用:Visual Studio 2015 使用:Microsoft.Net 4.6.1 Framework。