Winforms数据绑定:可以使用TypeConverter而不是Format / Parse事件吗?
在Winforms表单中,我想在输入字段包含无效值时向用户提供可视提示。 为此,我想将输入字段标签的ForeColor
属性绑定到底层模型的(boolean) IsPropertyValid
属性,以便在IsPropertyValid == false
时标签变为红色。
我目前拥有的是绑定的Format
事件的事件处理程序:
Controls["dateOfBirthLabel"].DataBindings["ForeColor"].Format += convertBoolToColor; // (dateOfBirthLabel.ForeColor is bound to a boolean IsDateOfBirthValid property.) void convertBoolToColor(object sender, ConvertEventArgs e) { e.Value = (bool)e.Value ? Color.Black : Color.Red; }
如果我想在WPF中执行此操作,我想我会直接使用XAML中的绑定指定自定义值转换器 ( bool
to Color
)。 最重要的是,我不必通过其名称引用特定控件。
我想用Winforms表单做同样的事情。 理想情况下,我可以直接在Forms Designer中为特定绑定指定TypeConverter
对象。 这可能吗?
我之前的回答(现已删除)不正确: 可以使用自定义TypeConverter
完成此操作。
首先,需要一个合适的转换器。 (与XAML不同,一个不实现IValueConverter
,而是从TypeConverter
派生。)例如:
// using System; // using System.ComponentModel; // using System.Drawing; // using System.Globalization; sealed class BooleanToColorConverter : TypeConverter { public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { return destinationType == typeof(Color); } public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { return (bool)value ? Color.Green : Color.Red; } }
接下来, (并且与XAML数据绑定不同),此转换器不应用于绑定本身 ; 它必须使用[TypeConverter]
属性附加到数据源的属性 :
// using System.ComponentModel; partial class DataSource : INotifyPropertyChanged { [TypeConverter(typeof(BooleanToColorConverter))] // <-- add this! public bool IsValid { get { … } set { … } } }
最后 ,必须在数据绑定上启用格式化 :
// Control control = …; // DataSource dataSource = …; control.DataBindings.Add("ForeColor", dataSource, "IsValid", formattingEnabled: true); // ^^^^^^^^^^^^^^^^^^^^^^^
请注意,此示例仅处理单向(数据源控制)数据绑定。 对于双向数据绑定,您还必须覆盖TypeConverter.ConvertFrom
和TypeConverter.CanConvertFrom
方法。
c.DataBindings.Add("Checked", dataSource, dataMember, true, DataSourceUpdateMode.OnPropertyChanged ); class Someclass { [TypeConverter(typeof(IntBoolConverter))] public int p_isEnable { get { return nc_isEnable; } set { m_isEnable= value); } } } public class IntBoolConverter:TypeConverter { public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { if (sourceType == typeof(bool)) { return true; } return base.CanConvertFrom(context, sourceType); } public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { if (destinationType == typeof(int)) { return true; } return base.CanConvertFrom(context, destinationType); } public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is bool) { var objectToInt = value.ObjectToBool(); return objectToInt; } return base.ConvertFrom(context, culture, value); } public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { if (destinationType == typeof(bool)) { return value.ObjectToBool(); } return base.ConvertTo(context, culture, value, destinationType); } }