wpf - plantillas - Desollado: Uso de un color como StaticResource para otro color
wpf templates (4)
¿Esta?
<Color x:Key="DarkBrown">#C4AF8D</Color>
<DynamicResource x:Key="TextBoxBackgroundColor" ResourceKey="DarkBrown"/>
<DynamicResource x:Key="ToolBarButtonForegroundColor" ResourceKey="DarkBrown"/>
Para casos de uso más avanzados y niveles múltiples de alias, vea esta respuesta .
Implementé skinning en mi aplicación. La aplicación carga su diccionario de recursos Brushes.xaml que utiliza colores que residen en un diccionario de recursos específico de la máscara. Por lo tanto, solo se carga un Color.xaml según la máscara elegida.
Color específico de la piel.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}" />
Como puede ver, los colores múltiples (TextBoxForegroundColor y ToolBarButtonForegroundColor) son los mismos. Me gustaría evitar eso, ya que cada vez es más confuso, sobre todo porque los colores utilizados no son reconocibles por su valor hexadecimal. Puede aconsejar ahora fusionar ambos colores en uno pero tengo máscaras donde el TextBoxForegroundColor es diferente del ToolBarButtonForegroundColor.
Lo que me gustaría hacer es algo como esto:
<Color x:Key="DarkBrown">#C4AF8D</Color>
<Color x:Key="TextBoxBackgroundColor" Color={StaticResource DarkBrown} />
<Color x:Key="ToolBarButtonForegroundColor" Color={StaticResource DarkBrown} />
¿Esto es posible en Xaml? No encontré la manera.
¿Por qué no haces que Brushes.xaml sea específico de la piel? Entonces tendrás esto:
<Color x:Key="DarkBrown">#C4AF8D</Color>
<SolidColorBrush x:Key="TextBoxBackgroundBrush" Color={StaticResource DarkBrown} />
<SolidColorBrush x:Key="ToolBarButtonForegroundBrush" Color={StaticResource DarkBrown} />
Otro punto a favor de hacer pinceles específicos para la piel es que hay situaciones en las que desearía hacer que ToolBarButtonForegroundBrush
un pincel de color sólido en una ToolBarButtonForegroundBrush
y una brocha de degradado en otra.
Esa última parte no es posible ya que un Color no tiene propiedad de Color.
Un color tiene una propiedad R, G, B y A. De modo que podría crear cuatro bytes como recursos:
<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>
Todavía no es lo que podrías preferir, pero debería funcionar.
La respuesta de HB es muy interesante y he jugado bastante con ella, ya que quiero hacer exactamente lo que esta pregunta me pide hacer.
Lo que noté es que usar DynamicResource no funciona para WPF 3.5. Es decir, arroja una excepción en el tiempo de ejecución (del que habla Amenti). Sin embargo, si crea colores que hacen referencia al color que desea compartir ... un StaticResource, funciona tanto en WPF 3.5 como en WPF 4.0.
Es decir, este xaml funciona tanto para WPF 3.5 como para 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>
Otra cosa que vale la pena mencionar (una vez más) es que este enfoque causa estragos en los diseñadores (es decir, los diseñadores de Visual Studio 2008 y 2010, los diseñadores de Blend 3 y 4). Yo especulo que esta es la misma razón por la cual a Kaxaml 1.7 no le gustaba la xaml de HB (si estás siguiendo el flujo de comentarios en la respuesta de HB).
Pero si bien rompe a los diseñadores para un caso de prueba simple, no parece romper la superficie de diseño para la aplicación a gran escala en la que trabajo en mi trabajo diario. Llano raro! En otras palabras, si le importan las cosas que todavía funcionan en el diseñador, intente de todos modos con este método ... ¡su diseñador aún puede funcionar!