In a Winforms form, I want to provide visual cues to the user when an input field contains an invalid value. To that end, I want to bind the ForeColor
property of a input field's label to the (boolean) IsPropertyValid
property of the underlying model such that the label turns red when IsPropertyValid == false
.
What I currently have is an event handler for the binding's Format
event:
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;
}
If I wanted to do this in WPF, I suppose I would specify a custom value converter (bool
to Color
) directly with the binding in the XAML. Most importantly, I wouldn't have to refer to a specific control via its name.
I would like to do the same thing with my Winforms form. Ideally, I could specify a TypeConverter
object for a particular binding directly in the Forms Designer. Is this possible?
My previous answer (now deleted) was incorrect: This can be done, using a custom TypeConverter
.
First, one needs a suitable converter. (Unlike with XAML, one does not implement a IValueConverter
, but derive from TypeConverter
.) For example:
// 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;
}
}
Next, (and also unlike with XAML data binding,) this converter is not applied to the binding itself; it must be attached to the data source's property using the [TypeConverter]
attribute:
// using System.ComponentModel;
partial class DataSource : INotifyPropertyChanged
{
[TypeConverter(typeof(BooleanToColorConverter))] // <-- add this!
public bool IsValid { get { … } set { … } }
}
Finally, formatting must be enabled on the data binding:
// Control control = …;
// DataSource dataSource = …;
control.DataBindings.Add("ForeColor", dataSource, "IsValid", formattingEnabled: true);
// ^^^^^^^^^^^^^^^^^^^^^^^
Note that this example only deals with one-way (data source to control) data binding. For two-way data binding, you would additionally have to override the TypeConverter.ConvertFrom
and TypeConverter.CanConvertFrom
methods.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With