Подтвердить что ты не робот

Скиннинг: использование цвета как статического источника для другого цвета

Я применил скиндинг в своем приложении. Приложение загружает свой ресурсный словарь Brushes.xaml, который использует цвета, которые находятся в словаре ресурсов, специфичном для скинов. Поэтому в зависимости от выбранного скина загружается только один Color.xaml.

Кожный цвет Color.xaml

    <Color x:Key="TextBoxBackgroundColor">#C4AF8D</Color>
    <Color x:Key="TextBoxForegroundColor">#6B4E2C</Color>
    <Color x:Key="ToolBarButtonForegroundColor">#6B4E2C</Color>

Brushes.xaml:

    <SolidColorBrush 
        x:Key="TextBoxBackground" 
        Color="{DynamicResource TextBoxBackgroundColor}" />
    <SolidColorBrush 
        x:Key="TextBoxForeground" 
        Color="{DynamicResource TextBoxForegroundColor}" />

Как вы можете видеть, несколько цветов (TextBoxForegroundColor и ToolBarButtonForegroundColor) одинаковы. Я хотел бы обойти это, поскольку он становится все более запутанным, потому что используемые цвета не распознаются по их шестнадцатеричному значению. Теперь вы можете посоветовать объединить оба цвета в один, но у меня есть скины, где TextBoxForegroundColor отличается от ToolBarButtonForegroundColor.

Что бы я хотел сделать, это примерно так:

<Color x:Key="DarkBrown">#C4AF8D</Color>

<Color x:Key="TextBoxBackgroundColor" Color={StaticResource DarkBrown} />
<Color x:Key="ToolBarButtonForegroundColor" Color={StaticResource DarkBrown} />

Возможно ли это в Xaml? Я не нашел способ.

4b9b3361

Ответ 1

Это?

<Color x:Key="DarkBrown">#C4AF8D</Color>

<DynamicResource x:Key="TextBoxBackgroundColor" ResourceKey="DarkBrown"/>
<DynamicResource x:Key="ToolBarButtonForegroundColor" ResourceKey="DarkBrown"/>

(Между прочим)

Ответ 2

H.B. Ответ очень интересный, и я немного поиграл с ним, так как хочу сделать именно то, что задает этот вопрос.

Я заметил, что использование DynamicResource не работает для WPF 3.5. То есть, он выдает исключение во время выполнения (о чем говорит Amenti). Однако , если вы делаете цвета, которые ссылаются на цвет, который вы хотите использовать... StaticResource, он работает как с WPF 3.5, так и с WPF 4.0.

То есть, этот xaml работает как для WPF 3.5, так и для WPF 4.0:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="ColorsReferencingColors.MainWindow"
    x:Name="Window"
    Title="MainWindow"
    Width="640"
    Height="480"
>
    <Window.Resources>
        <Color x:Key="DarkBlue">DarkBlue</Color>
        <StaticResource x:Key="EllipseBackgroundColor" ResourceKey="DarkBlue"/>
        <SolidColorBrush
            x:Key="ellipseFillBrush"
            Color="{DynamicResource EllipseBackgroundColor}"
        />
    </Window.Resources>
    <Grid>
        <StackPanel Margin="25">
            <Ellipse
                Width="200"
                Height="200"
                Fill="{DynamicResource ellipseFillBrush}"
            />
        </StackPanel>
    </Grid>
</Window>

Еще одна вещь, которая упоминается (снова), заключается в том, что этот подход наносит ущерб дизайнерам (например, разработчикам Visual Studio 2008 и 2010, дизайнерам Blend 3 и 4). Я предполагаю, что это та же самая причина, почему Kaxaml 1.7 не нравился H.B. xaml (если вы следуете за комментарием на ответ H.B.).

Но пока он разбивает дизайнеров на простой тестовый пример, он, похоже, не разбивает поверхность дизайна для крупномасштабного приложения, над которым я работаю в своей дневной работе. Просто странно! Другими словами, если вы заботитесь о вещах, которые все еще работают в дизайнере, попробуйте этот метод в любом случае... ваш дизайнер может по-прежнему работать!

Ответ 3

Почему бы вам просто не сделать Brushes.xaml для конкретной кожи? Тогда вы получите следующее:

<Color x:Key="DarkBrown">#C4AF8D</Color>

<SolidColorBrush x:Key="TextBoxBackgroundBrush" Color={StaticResource DarkBrown} />
<SolidColorBrush x:Key="ToolBarButtonForegroundBrush" Color={StaticResource DarkBrown} />

Еще один момент в пользу создания кистей, специфичных для кожи, заключается в том, что есть ситуации, когда вы хотите сделать ToolBarButtonForegroundBrush сплошную кисть на одном скине и градиентную кисть в другой.

Ответ 4

Эта последняя часть невозможна, так как цвет не имеет свойства цвета.

A Цвет имеет свойства R, G, B и A. Таким образом, вы можете создать четыре байта в качестве ресурсов:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:sys="clr-namespace:System;assembly=mscorlib">
    <sys:Byte x:Key="r">#23</sys:Byte>
    <sys:Byte x:Key="g">#45</sys:Byte>
    <sys:Byte x:Key="b">#67</sys:Byte>
    <sys:Byte x:Key="a">#FF</sys:Byte>

    <Color x:Key="c1" R="{StaticResource r}"
       G="{StaticResource g}"
       B="{StaticResource b}"
       A="{StaticResource a}"/>

    <Color x:Key="c2" R="{StaticResource r}"
       G="{StaticResource g}"
       B="{StaticResource b}"
       A="{StaticResource a}"/>

</ResourceDictionary>

Все еще не то, что вы можете предпочесть, но оно должно работать.