在我的WinForms应用程序中,我实现了
custom data binding with support for value converters
,类似于WPF。
示例有一个新的绑定类,该类派生自
Binding
并允许连接自定义转换器:
public class CustomBinding : Binding
{
private readonly IValueConverter _converter;
private readonly object _converterParameter;
private readonly CultureInfo _converterCulture;
public CustomBinding(string propertyName, object dataSource, string dataMember, IValueConverter valueConverter, CultureInfo culture, object converterParameter = null)
: base(propertyName, dataSource, dataMember)
{
if (valueConverter != null)
this._converter = valueConverter;
this.DataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged;
this.FormattingEnabled = false;
this._converterCulture = culture;
this._converterParameter = converterParameter;
}
public CustomBinding(string propertyName, object dataSource, string dataMember, IValueConverter valueConverter, object converterParameter = null)
: base(propertyName, dataSource, dataMember)
{
if (valueConverter != null)
this._converter = valueConverter;
this._converterCulture = Thread.CurrentThread.CurrentUICulture;
this._converterParameter = converterParameter;
}
protected override void OnFormat(ConvertEventArgs cevent)
{
if (this._converter != null)
{
var converterdValue = this._converter.Convert(cevent.Value, cevent.DesiredType, _converterParameter, _converterCulture);
cevent.Value = converterdValue;
}
else base.OnFormat(cevent);
}
protected override void OnParse(ConvertEventArgs cevent)
{
if (this._converter != null)
{
var converterdValue = this._converter.ConvertBack(cevent.Value, cevent.DesiredType, _converterParameter, _converterCulture);
cevent.Value = converterdValue;
}
else base.OnParse(cevent);
}
}
还有界面
IValueConverter
这类似于WPF的界面:
public interface IValueConverter
{
object Convert(object value, Type targetType, object parameter, CultureInfo culture);
object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture);
}
有了这个,我可以将自己的转换器连接到任何(双向)绑定。到目前为止,我已经建立了一个
TimeSpanStringValueConverter
允许我绑定
TimeSpan
字段到文本框以及
InvertBooleanValueConverter
将布尔字段的反面绑定到任何控件的任何布尔属性。他们按预期工作!
现在我要绑定类型为
double?
到文本框
Text
领域为此,我编写了以下转换器:
public class NullableDoubleStringValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value != null ? ((double)value).ToString(culture) : String.Empty;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string text = Regex.Replace((string)value, @"[^0-9" + culture.NumberFormat.NumberDecimalSeparator + @"]", "");
if (text == String.Empty)
{
return null;
}
double convertedValue;
if (Double.TryParse(text, NumberStyles.Any, culture, out convertedValue))
{
return (double?)convertedValue;
}
return null;
}
}
我用这种方式将它绑定到文本框:
this.textBox1.DataBindings.Add(new CustomBinding("Text", obj, "MyProperty", new NullableDoubleStringValueConverter())); // obj is the data context object
当我在
ConvertBack
值转换器的方法我可以清楚地看到,在成功地离开文本框后,字符串将如何转换为可为空的双值。但是,与我的其他情况不同,它不会更新数据上下文对象。如果我在
Convert
方法,我可以看到它将检索
MyProperty
当更新
文本
离开文本框后。因此,在文本框中键入任何数值后,文本框将变为空。
我的问题是:为什么?我如何才能使它与可为null的类型一起工作(
双重的
)? 如果我更改
我的属性
在数据上下文对象中
double
它将接受我更改的值。
不幸的是,我需要可以为空的支持。因此,当文本框为空时,我希望存储空值,并在值为空时显示空文本框。
Download of Problem Case Solution