【问题标题】:Create your own system colors创建自己的系统颜色
【发布时间】:2011-03-30 18:57:40
【问题描述】:

基本上,我如何在静态类或类似的类中创建自己的一组颜色,以便我可以执行以下操作:

存在什么

<Setter ... Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>

我想要什么

<Setter ... Value="{DynamicResource {x:Static MyColors.Color1}}"/>

【问题讨论】:

    标签: wpf resources colors dynamicresource staticresource


    【解决方案1】:

    资源键可以是任何东西,因此您可以同时使用Color 作为键和值:

    public static class MyColors
    {
        static MyColors()
        {
            App.Current.Resources.Add(MyHighlightColorKey, MyHighlightColorKey);
        }
    
        public static readonly Color MyHighlightColorKey = Color.FromArgb(255, 0, 88, 0);
    }
    

    静态构造函数使用自身作为应用程序资源的键来添加颜色。

    (SystemColors 在内部为每个定义的颜色或画笔使用 SystemResourceKeys,但是您无法访问该类(这是有道理的),或者如果您对使用值作为自己的键)

    你可以这样使用它:

    <TextBox>
        <TextBox.Background>
            <SolidColorBrush Color="{DynamicResource {x:Static local:MyColors.MyHighlightColorKey}}"/>
        </TextBox.Background>
    </TextBox>
    

    如果您需要在本地级别覆盖密钥,您也可以这样做:

    <Window.Resources>
        <Color x:Key="{x:Static local:MyColors.MyHighlightColorKey}" A="255" R="255" G="0" B="0"/>
    </Window.Resources>
    

    编辑:如果你有很多颜色、画笔和诸如此类的东西,你也可以使用反射在构造函数中进行资源注册(我使用字段,如果你使用属性来公开你需要的数据稍微调整一下):

    static MyColors()
    {
        FieldInfo[] keyFieldInfoArray = typeof(MyColors).GetFields();
        foreach (var keyFieldInfo in keyFieldInfoArray)
        {
            object value = keyFieldInfo.GetValue(null);
            App.Current.Resources.Add(value, value);
        }
    }
    

    【讨论】:

    • 这正是我想知道的。非常感谢 H.B.!
    • 我对使用 App.current.resources.add() 添加资源的部分有点困惑。这实际上是做什么的?使用 {x:Static local:MyColors.MyHighlightColorKey} 访问颜色时,这一步似乎是不必要的
    • @redshift5:这会将颜色作为资源添加到允许本地覆盖的应用程序中,这就是为什么您不会直接使用x:Static,而是使用DynamicResource
    • @H.B.谢谢,我明白了。使用 {DynamicResource {x:Static local:MyColors.MyHighlightColorKey}}{x:Static local:MyColors.MyHighlightColorKey} 有什么优势吗?或者将其添加为资源后,您可以像{DynamicResource MyHighlightColorKey} 一样简单地使用它吗?
    • @redshift5:正如我所说,如果颜色是通过{DynamicResource {x:Static ...}} 引用的,您只能在本地ResourceDictionary 中覆盖,如果您直接使用x:Static,您将始终获得颜色为它是在类中定义的,这与它首先是资源键无关。关于{DynamicResource MyHighlightColorKey}:这不起作用,因为这里MyHighlightColorKey 将被解释为字符串键,但颜色是使用自身作为键注册的。
    【解决方案2】:

    我想我会加入另一种选择。您可以通过执行以下操作来使用静态资源...

    public struct MyColors
    {
        public static Brush Color1
        {
            get { return Brushes.Red; } // or whatever you like
        }
        public static Brush Color2
        {
            get { return Brushes.Blue; }
        }
    }
    

    然后在您的 XAML 中,使用:

    "{x:Static local:MyColors.Color1}"
    

    我刚刚花了 10 分钟试图让它与 DynamicResource 扩展一起工作,但我做不到。如果有人知道如何(或为什么),请告诉我们:)

    【讨论】:

    • 我喜欢这个,简单多了。
    • 要将其用作资源,您需要将其添加到资源字典中,因为 SystemColors 发生在幕后,并且这些资源在应用程序级别不可见。有关资源方法,请参阅我的答案。
    【解决方案3】:

    您可以轻松做到这一点。您必须定义以下类:

    public class MyColors
    {
        public static string Color1{ get{return "Color1Key";}}
    }
    

    例如,在您的App.xaml 中,您可以这样做:

    <Application ...>
        <Application.Resources>
            <Color x:Key="Color1Key">#FF969696</Color>
        </Application.Resources>
    </Application>
    

    由于静态字符串实际上只是用于强类型,我通常不创建这样的静态类,而只使用我定义的任何键,所以它变成:

    <Setter ... Value="{DynamicResource Color1Key}"/>
    

    (我相信你也可以在&lt;Color x:Key="{x:Static MyColors.Color1}"&gt;#FF969696&lt;/Color&gt; 中使用强类型,但我现在不确定......)

    (还要注意使用 x:Static 时,您必须指定 MyColors 所在的命名空间,因此它变为 {x:Static local:MyColors.Color1}

    【讨论】:

      猜你喜欢
      • 2018-01-07
      • 1970-01-01
      • 2017-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-22
      相关资源
      最近更新 更多