It would be useful to attach a bunch of custom properties to standard controls in .NET, without creating a set of custom controls.
I heard that its possible with WPF, but does somebody knows a solution for plain winform application?
Why? For example, when a control has the focus and its a TextBox, or a DropDownList or a ComboBox, then I want to paint its backcolor in the custom property I could name: "focusColor"
And of course, I do not want to create custom buttons, combos or dropdown...
In WPF it is done with attached properties. Although there is no exact equivalent in Windows Form, you can implement an IExtenderProvider
to "attach" a custom property to a control. This property can then be used in the designer, like a normal property. See the code provided in this blog post for an example.
Here's an implementation for your "FocusColor" example:
[ProvideProperty("FocusColor", typeof(Control))]
public class FocusColorProvider : Component, IExtenderProvider
{
private readonly Dictionary<IntPtr, Color> _focusColors;
private readonly Dictionary<IntPtr, Color> _backColors;
public FocusColorProvider()
{
_focusColors = new Dictionary<IntPtr, Color>();
_backColors = new Dictionary<IntPtr, Color>();
}
public bool CanExtend(object extendee)
{
return (extendee is Control);
}
public Color GetFocusColor(Control ctl)
{
Color color;
if (_focusColors.TryGetValue(ctl.Handle, out color))
{
return color;
}
return ctl.BackColor;
}
public void SetFocusColor(Control ctl, Color color)
{
Color backColor;
if (!_backColors.TryGetValue(ctl.Handle, out backColor))
{
backColor = ctl.BackColor;
}
// Same color as BackColor, disable the behavior
if (color == backColor)
{
RemoveFocusColor(ctl);
ctl.LostFocus -= ctl_LostFocus;
ctl.GotFocus -= ctl_GotFocus;
_focusColors.Remove(ctl.Handle);
}
else
{
_focusColors[ctl.Handle] = color;
if (ctl.Focused)
ApplyFocusColor(ctl);
ctl.LostFocus += ctl_LostFocus;
ctl.GotFocus += ctl_GotFocus;
}
}
void ctl_GotFocus(object sender, EventArgs e)
{
ApplyFocusColor((Control)sender);
}
void ctl_LostFocus(object sender, EventArgs e)
{
RemoveFocusColor((Control)sender);
}
void ApplyFocusColor(Control ctl)
{
_backColors[ctl.Handle] = ctl.BackColor;
ctl.BackColor = GetFocusColor(ctl);
}
void RemoveFocusColor(Control ctl)
{
Color color;
if (_backColors.TryGetValue(ctl.Handle, out color))
{
ctl.BackColor = color;
_backColors.Remove(ctl.Handle);
}
}
}
Add this code to your project, compile, and add a FocusColorProvider
on your form using the designer. A new FocusColor
property should appear on the property grid when you select a control, just set it to the color you want. The control's BackColor will be changed to this color when it takes focus.
You can utilize the Tag
property of each control to store custom data associated with that control. Create a class MyCustomAttributes
and assign objects of that type to MyControl.Tag
. This won't work in the designer, of course, only at run time.
As an alternative, you could derive some classes like ExtTextBox
from TextBox
, ExtDropDownList
from DropDrownList
etc., having some additional attributes. That is a very simple and painless way of creating custom controls, which might be acceptable in your case, even if you said you don't want such a solution.
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