web-dev-qa-db-fra.com

Dépouillement: utilisation d'une couleur comme ressource statique pour une autre couleur

J'ai implémenté le skinning dans mon application. L'application charge son dictionnaire de ressources Brushes.xaml qui utilise des couleurs qui résident dans un dictionnaire de ressources spécifique à l'habillage. Ainsi, un seul Color.xaml est chargé selon la peau choisie.

Couleur spécifique à la peau.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}" />

Comme vous pouvez le voir, plusieurs couleurs (TextBoxForegroundColor et ToolBarButtonForegroundColor) sont identiques. J'aimerais contourner cela car cela devient de plus en plus déroutant, d'autant plus que les couleurs utilisées ne sont pas reconnaissables par leur valeur hexadécimale. Vous pouvez maintenant conseiller de fusionner les deux couleurs en une seule, mais j'ai des habillages où TextBoxForegroundColor est différent de ToolBarButtonForegroundColor.

Ce que je voudrais faire, c'est quelque chose comme ceci:

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

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

Est-ce que cela est possible dans Xaml? Je n'ai pas trouvé de moyen.

43
Amenti

Cette?

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

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

Pour les cas d'utilisation plus avancée et plusieurs niveaux de voir aliasing cette réponse .

43
H.B.

Pourquoi ne faites-vous pas simplement Brushes.xaml spécifique à la peau? Ensuite, vous aurez ceci:

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

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

Un autre point en faveur de la peau spécifique faisant des brosses est qu'il ya des situations où vous voulez faire le ToolBarButtonForegroundBrush une brosse couleur unie dans une peau et une brosse gradient dans un autre.

9
Pavlo Glazkov

La réponse de H. B. est très intéressante et je l'ai joué avec un peu puisque je veux faire exactement ce que cette question demande de le faire.

Ce que j'ai remarqué, c'est que l'utilisation d'un DynamicResource ne fonctionne pas pour WPF 3.5. Autrement dit, il lève une exception au moment de l'exécution (celui dont Amenti parle). Cependant, si vous faites des couleurs qui font référence à la couleur que vous souhaitez partager ... un StaticResource, il fonctionne aussi bien sur WPF 3.5 et WPF 4.0.

Autrement dit, ce xaml fonctionne à la fois pour WPF 3.5 et 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>

Une autre chose qui mérite d'être mentionné (encore une fois) est que le chaos de cette approche avec les concepteurs là-bas (i.e. Visual Studio 2008 et 2010 designers, Blend 3 et 4 designers). Je spécule que c'est la même raison pour laquelle Kaxaml 1.7 n'a pas goût de XAML de H.B. (si vous suivez le flux de commentaires sur la réponse de H. B.).

Mais alors qu'il brise les concepteurs pour un test de simple, il ne semble pas briser la surface de conception pour la application à grande échelle je travaille dans mon travail de jour. Tout simplement bizarre! En d'autres termes, si vous vous souciez de choses qui fonctionnent toujours dans le concepteur, essayez de toute façon cette méthode ... votre concepteur peut toujours fonctionner!

7
cplotts

Cette dernière partie n'est pas possible car une Couleur n'a pas de propriété Couleur.

Une couleur a une propriété R, G, B et A. Vous pouvez donc créer quatre octets en tant que ressources:

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

Toujours pas ce que vous préférez, mais cela devrait fonctionner.

3
Erno de Weerd