C#:自定义颜色类可供解决方案中的所有项目访问

nbz*_*nbz 3 c# colors winforms

我有一个自定义颜色列表,我在我的解决方案的所有UI元素中使用它(包含多个项目).我可以在其中一个项目中创建一个静态类,其中我可以为我的颜色提供自定义名称,然后在各个点访问它们,但是对于多个项目是否有更好的解决方案?

static class MyColors
{
   public static myColor1 = Color.FromArgb(239, 247, 172);
   .
   .
   . 
}
Run Code Online (Sandbox Code Playgroud)

是否也可以在控件的属性网格中查看这些自定义颜色?例如,我的大多数背景都有一个自定义颜色,而不是复制RGB值,我希望能够选择我的自定义颜色.我知道我可以使用MyColors类以编程方式对其进行编码,但如果有办法将其添加到属性网格中会很好.

谢谢!

Kev*_*ick 9

好的,我即将发布一个很长的答案,说明这是不可能的,但经过一些研究后我发现了你想要做的事情!

首先,使用静态类来存储颜色是存储常用颜色的常用且可接受的方式.您可以继续使用该方法.

以下是在设计器中公开这些颜色所需要做的事情:

  1. 创建一个CustomColors封装自定义颜色的类.
  2. 创建一个TypeConverter可以在string和之间转换的CustomColor
  3. 创建一个IExtenderProvider可以在表单上添加一个CustomForeColorCustomBackColor所有控件.
  4. 在您想要使用自定义颜色的任何地方,您只需要将扩展​​程序提供程序添加到表单中(编译后它将显示在工具箱中),然后CustomForeColor和CustomBackColor将显示为所有控件的虚拟属性,并且具有良好的拖放效果下.

这是最终结果:

在此输入图像描述

天空是极限,如果你愿意,你可以创建一个自定义的UITypeEditor来实际绘制属性网格中的颜色,但这可能没有必要,因为你可以检查ForeColor和BackColor属性.这里有很多关于如何做到这一点的有用信息:

http://msdn.microsoft.com/en-us/library/aa302326.aspx

这是代码:

CustomColor.cs

[TypeConverter(typeof(CustomColorTypeConverter))]
public class CustomColor
{
    public static CustomColor Stop = new CustomColor { Color = Color.Red };
    public static CustomColor Go = new CustomColor { Color = Color.Green };
    public static CustomColor Yield = new CustomColor { Color = Color.Yellow };

    public Color Color { get; private set; }

    internal static CustomColor Find(Color color)
    {
        if (color == CustomColor.Stop.Color)
            return CustomColor.Stop;
        else if (color == CustomColor.Go.Color)
            return CustomColor.Go;
        else if (color == CustomColor.Yield.Color)
            return CustomColor.Yield;

        return new CustomColor { Color = Color.Transparent };
    }
}
Run Code Online (Sandbox Code Playgroud)

CustomColorTypeConverter.cs

public class CustomColorTypeConverter : StringConverter
{
    static Dictionary<CustomColor, string> _nameIndex = InitializeNameIndex();
    static Dictionary<string, CustomColor> _colorIndex = InitializeColorIndex();

    private static Dictionary<string, CustomColor> InitializeColorIndex()
    {
        return typeof(CustomColor)
            .GetFields(BindingFlags.Public | BindingFlags.Static)
            .ToDictionary(f => f.Name, f => (CustomColor)f.GetValue(null));
    }

    private static Dictionary<CustomColor, string> InitializeNameIndex()
    {
        return typeof(CustomColor)
            .GetFields(BindingFlags.Public | BindingFlags.Static)
            .ToDictionary(f => (CustomColor)f.GetValue(null), f => f.Name);
    }

    public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
    {
        return true;
    }

    public override TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
    {
        return new System.ComponentModel.TypeConverter.StandardValuesCollection(_nameIndex.Values.ToList());
    }

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        if (destinationType == typeof(string))
            return true;

        return base.CanConvertTo(context, destinationType);
    }

    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        if (sourceType == typeof(CustomColor))
            return true;

        return base.CanConvertFrom(context, sourceType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
    {
        if (value is string)
        {
            CustomColor result;
            if (_colorIndex.TryGetValue((string)value, out result))
                return result;
            else
                return new CustomColor();
        }

        return base.ConvertFrom(context, culture, value);
    }

    public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
    {
        if (destinationType == typeof(string) && value is CustomColor)
        {
            string result;
            if (_nameIndex.TryGetValue((CustomColor)value, out result))
                return result;
            else
                return String.Empty;
        }
        else
        {
            return base.ConvertTo(context, culture, value, destinationType);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

CustomColorExtenderProvider.cs

[ProvideProperty("CustomForeColor", typeof(Control))]
[ProvideProperty("CustomBackColor", typeof(Control))]
public class CustomColorExtenderProvider : Component, IExtenderProvider
{
    public CustomColor GetCustomForeColor(Control control)
    {
        return CustomColor.Find(control.ForeColor);
    }

    public CustomColor GetCustomBackColor(Control control)
    {
        return CustomColor.Find(control.BackColor);
    }

    public void SetCustomBackColor(Control control, CustomColor value)
    {
        control.BackColor = value.Color;
    }

    public void SetCustomForeColor(Control control, CustomColor value)
    {
        control.ForeColor = value.Color;
    }

    public bool ShouldSerializeCustomForeColor(Control control)
    {
        return false;
    }

    public bool ShouldSerializeCustomBackColor(Control control)
    {
        return false;
    }

    #region IExtenderProvider Members

    public bool CanExtend(object extendee)
    {
        return (extendee is Control);
    }

    #endregion
}
Run Code Online (Sandbox Code Playgroud)