Скиннинг: использование цвета в качестве статического ресурса для другого цвета - PullRequest
42 голосов
/ 26 января 2011

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

Skin-Specific 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.

Я хотел бы сделать что-то вроде этого:это вообще возможно в Xaml?Я не нашел пути.

Ответы [ 4 ]

43 голосов
/ 26 января 2011

Это

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

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

Для более сложных вариантов использования и нескольких уровней псевдонимов см. этот ответ .

9 голосов
/ 26 января 2011

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

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

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

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

7 голосов
/ 11 марта 2011

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

Что я заметил, так это то, что использование DynamicResource не 't работает для WPF 3.5.То есть, он генерирует исключение во время выполнения (тот, о котором говорит Аменти).Однако , если вы создаете цвета, которые ссылаются на цвет, которым вы хотите поделиться ... 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 не понравился xaml HB (если вы следите за потоком комментариев по ответу HB).

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

3 голосов
/ 26 января 2011

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

Цвет имеет свойства 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>

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...