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

时间:2012-01-13 14:40:57

标签: c# winforms colors

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

static class MyColors
{
   public static myColor1 = Color.FromArgb(239, 247, 172);
   .
   .
   . 
}

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

谢谢!

2 个答案:

答案 0 :(得分:9)

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

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

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

  1. 创建一个封装自定义颜色的CustomColors类。
  2. 创建可在TypeConverterstring
  3. 之间转换的CustomColor
  4. 创建IExtenderProvider,为表单上的所有控件添加CustomForeColorCustomBackColor
  5. 您想要使用自定义颜色的任何地方,只需将扩展程序提供程序添加到表单中(编译后它将显示在工具箱中),然后CustomForeColor和CustomBackColor将显示为所有控件的虚拟属性,一个很好的下拉。
  6. 这是最终结果:

    enter image description here

    天空是极限,如果你愿意,你可以创建一个自定义的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 };
        }
    }
    

    <强> 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);
            }
        }
    }
    

    <强> 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
    }
    

答案 1 :(得分:0)

我说得很简单:定义了一个静态类,例如

public static class GraphicalProperties
{
    public static readonly Color    ControlBackColor    = Color.FromArgb(128, 32, 48);
    public static readonly Color    ControlForeColor    = Color.White;
    public static readonly Font     ControlFont         = new Font("Consolas", 10);
}

然后,您只需在每个控件的构造函数中添加

public MyForm()
{
    InitializeComponent();

    BackColor   = GraphicalProperties.ControlBackColor;
    ForeColor   = GraphicalProperties.ControlForeColor;
    Font        = GraphicalProperties.ControlFont;
}

这提供了很少的自动功能,并且在“属性网格”中没有任何条目,但是非常简单,并且在我看来是可行的。