Skinning: Using a Color as StaticResource for another Color

后端 未结 4 1990
遇见更好的自我
遇见更好的自我 2020-12-03 00:17

I implemented skinning in my application. The application loads its Brushes.xaml resource dictionary which uses colors which reside in a skin-specific resource dictionary. S

相关标签:
4条回答
  • 2020-12-03 00:57

    H.B.'s answer is very interesting and I have played around with it quite a bit since I want to do exactly what this question is asking to do.

    What I've noticed is that using a DynamicResource doesn't work for WPF 3.5. That is, it throws an exception at run time (the one Amenti talks about). However, if you make colors that are referencing the color you want to share ... a StaticResource, it works on both WPF 3.5 and WPF 4.0.

    That is, this xaml works for both WPF 3.5 and 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>
    

    Another thing that bears mentioning (again) is that this approach wreaks havoc with the designers out there (i.e the Visual Studio 2008 and 2010 designers, the Blend 3 and 4 designers). I speculate that this is the same reason why Kaxaml 1.7 wasn't liking H.B.'s xaml (if you're following the comment stream on H.B.'s answer).

    But while it breaks the designers for a simple test case, it doesn't seem to break the design surface for the large scale application I work on in my day job. Plain weird! In other words, if you care about things still working in the designer, try this method out anyway ... your designer may still work!

    0 讨论(0)
  • 2020-12-03 01:01

    This?

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

    For more advanced use cases and multiple levels of aliasing see this answer.

    0 讨论(0)
  • 2020-12-03 01:05

    Why don't you just make Brushes.xaml skin-specific? Then you will have this:

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

    Another point in favor of making brushes skin-specific is that there are situations where you would want to make the ToolBarButtonForegroundBrush a solid color brush in one skin and a gradient brush in another skin.

    0 讨论(0)
  • 2020-12-03 01:10

    That last part is not possible as a Color has no Color property.

    A Color does have an R, G, B and A property. So you could create four bytes as resources:

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

    Still not what you might prefer but it should work.

    0 讨论(0)
提交回复
热议问题