I am using INotifyPropertyChanged to propagate changes in my WinForm application.
In this case, I have code that converts the timestamp of an entire UNIX chain and a System DateTime object. It receives a ConvertEventArgs object, which contains the value of the object and the desired type to convert.
By using INotifyPropertyChanged and adding a dynamic binding to the control, you can provide handlers that feed the DesiredType in the ConvertEventArg object.
I have a base class that I call NotifyBase that includes this static function:
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)
The base class also implements this:
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;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
Then I initialize my data. Here is an example with 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>();
}
}
, , "is", , .
, , int, , :

:
, is object.GetType() == typeof(int). ?
, , .
, , GetType().
: Visual Studio 2015
: Microsoft.Net 4.6.1 Framework.