Winforms .NET将自定义属性添加到winform控件

Winforms .NET将自定义属性添加到winform控件,winforms,properties,custom-controls,Winforms,Properties,Custom Controls,将一组自定义属性附加到.NET中的标准控件,而不创建一组自定义控件将非常有用 我听说WPF是可能的,但有人知道一个简单winform应用程序的解决方案吗 为什么??例如,当一个控件有焦点和文本框、下拉列表或组合框时,我想在自定义属性中绘制其背景色,我可以命名为:“focusColor” 当然,我不想在WPF中创建自定义按钮、组合或下拉菜单…。虽然Windows窗体中没有完全等效的控件,但可以实现将自定义属性“附加”到控件。然后,该属性可以像普通属性一样在设计器中使用。有关示例,请参见中提供的代码

将一组自定义属性附加到.NET中的标准控件,而不创建一组自定义控件将非常有用

我听说WPF是可能的,但有人知道一个简单winform应用程序的解决方案吗

为什么??例如,当一个控件有焦点和文本框、下拉列表或组合框时,我想在自定义属性中绘制其背景色,我可以命名为:“focusColor”

当然,我不想在WPF中创建自定义按钮、组合或下拉菜单…

。虽然Windows窗体中没有完全等效的控件,但可以实现将自定义属性“附加”到控件。然后,该属性可以像普通属性一样在设计器中使用。有关示例,请参见中提供的代码

下面是“FocusColor”示例的一个实现:

[提供属性(“聚焦颜色”,类型(控制))]
公共类FocusColorProvider:组件,IExtenderProvider
{
专用只读词典_focusColors;
私人只读词典(backColors);;
公共焦点颜色提供者()
{
_focusColors=新字典();
_backColors=新字典();
}
公共bool CanExtend(对象extendee)
{
返回(extendee为控制);
}
公共颜色GetFocusColor(控制ctl)
{
颜色;
if(_focusColors.TryGetValue(控制柄,输出颜色))
{
返回颜色;
}
返回ctl.BackColor;
}
公共无效SetFocusColor(控制ctl,颜色)
{
彩色底色;
if(!\u backColors.TryGetValue(ctl.Handle,out backColor))
{
backColor=ctl.backColor;
}
//与背景色相同的颜色,禁用该行为
如果(颜色==背景色)
{
去除焦点颜色(ctl);
ctl.LostFocus-=ctl_LostFocus;
ctl.GotFocus-=ctl_GotFocus;
_焦点颜色。移除(控制手柄);
}
其他的
{
_焦点颜色[ctl.Handle]=颜色;
如果(控制聚焦)
ApplyFocusColor(ctl);
ctl.LostFocus+=ctl_LostFocus;
ctl.GotFocus+=ctl_GotFocus;
}
}
void ctl_GotFocus(对象发送方,事件参数e)
{
ApplyFocusColor((控制)发送器);
}
void ctl_LostFocus(对象发送方,事件参数e)
{
移除聚焦颜色((控制)发送器);
}
无效ApplyFocusColor(控制ctl)
{
_backColors[ctl.Handle]=ctl.BackColor;
ctl.BackColor=GetFocusColor(ctl);
}
无效清除聚焦颜色(控制ctl)
{
颜色;
if(_backColors.TryGetValue(ctl.Handle,out color))
{
ctl.BackColor=颜色;
_背景色。移除(控制手柄);
}
}
}

将此代码添加到项目中,使用设计器编译并在表单上添加
FocusColorProvider
。选择控件时,属性网格上应显示一个新的
FocusColor
属性,只需将其设置为所需的颜色即可。当控件聚焦时,其背景色将更改为该颜色。

您可以利用每个控件的
标记属性来存储与该控件关联的自定义数据。创建一个类
MyCustomAttributes
,并将该类型的对象分配给
MyControl.Tag
。当然,这在设计器中不起作用,只在运行时起作用


或者,您可以从
TextBox
派生一些类,如
ExtTextBox
ExtDropDownList
dropdownlist
等,这些类具有一些附加属性。这是一种创建自定义控件的非常简单和轻松的方法,在您的情况下,这可能是可以接受的,即使您说您不想要这样的解决方案。

Wow!托马斯,需要更多的帮助!。。。当我在一个新项目中复制/粘贴代码时,我必须添加“using System.ComponentModel;”,并且我有两个错误:“找不到控件的类型或名称空间”和“Color”相同。无法编译类:-(哦,让它工作起来了,只需要使用system.drawing和system.windows.forms添加
[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);
        }
    }
}