views:

283

answers:

2

Hi,

We are looking at starting a new Silverlight project using the PRISM framework (to benefit from modules etc) and I am still a little unclear about the best styling approach. What I'd ideally like is to have editable XAML files (maybe even just 1 for the whole project) containing the application's style so that they can be edited to change the look and feel of the application without having to recompile everything. Is this approach something people use? I guess it would need to load the file in at startup and apply the style which I assume wouldn't be a massive overhead.

Just wondering what approaches people use

Thanks for your time

+1  A: 

In Silverlight (and WPF) the typical/normal approach is to keep your styles and brushes in a Resource Dictionary. these can then be swapped out to change the layout, colors, and control templates at any time. You can include them in the XAP that is generated when you build the app or in a stand-alone assembly.

The thing to remember is that the resource files can be loaded at differing levels. The application level down to the level of the individual controls. the dictionaries that are loaded at the lower level will take precedence over the higher level one. For me, it helps to think of it like layers.

Muad'Dib
+1  A: 

Hi Suiva,

Here's my approach-

In your App.xaml you'll want to declare a MergedDictionaries element like this..

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Styles\Colors.xaml" />
            <ResourceDictionary Source="Styles\Brushes.xaml" />
            <ResourceDictionary Source="Styles\Typeography.xaml" />
            <ResourceDictionary Source="Styles\ModuleAStyles.xaml />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

As you can see, I tend to have a few seperate files here for colors (Colours if you're spelling it properly), brushes, Typeography and then I generally use one extra for each Module. Use more than one if it's a large app else you'll end up with too much stuff in one file and it quickly gets difficult to maintain. You'll just have to use your best judgement here and see what fits best for you.

In the Typeography.xaml that I'm referencing in that merged dictionary I have declared a style called ApplicationTitle like this...

<!--Application Title-->
<Style TargetType="{x:Type TextBlock}"
       x:Key="ApplicationTitle">
    <Setter Property="VerticalAlignment"
            Value="Center" />
    <Setter Property="HorizontalAlignment"
            Value="Center" />
    <Setter Property="FontFamily"
            Value="Georgia" />
    <Setter Property="Foreground"
            Value="{StaticResource ResourceKey=FlatGradientLightest}" />
    <Setter Property="FontSize"
            Value="24" />
    <Setter Property="Effect">
        <Setter.Value>
            <DropShadowEffect BlurRadius="5"
                              Color="#333"
                              Opacity=".3" />
        </Setter.Value>
    </Setter>
</Style>

You'll notice that in this style I'm again referencing another resource called 'FlatGradientLightest' using the StaticResource markup extension. This resource exists in the Brushes.xaml file...

    <!--Flat Diagonal Gradient Lightest-->
<LinearGradientBrush x:Key="FlatDiagonalGradientLightest"
                     StartPoint="0,0"
                     EndPoint="1,1">
    <GradientStop Color="{StaticResource ResourceKey=Light}"
                  Offset="0" />
    <GradientStop Color="{StaticResource ResourceKey=Lightest}"
                  Offset="1" />
</LinearGradientBrush>

And again this references the Colors 'Light' and 'Lightest'. These exist in the Colors.xaml file...

<Color x:Key="Light"
       A="255"
       R="190"
       G="190"
       B="190" />
<Color x:Key="Lightest"
       A="255"
       R="250"
       G="250"
       B="250" />

What's important here is the order I specified the resource dictionaries in App.xaml. If I were to move Typeography.xaml to the top of the list, it would cause a runtime since at the time it loaded this style, it's dependencies wouldn't exist.

Since WPF/SL look upwards to resolve resources (as Muad'Dib) pointed out, you can just use these resources in your modules as if they were declared locally. So in one of my modules, I have a TextBlock declared like this...

<TextBlock Text="Menu Module Loaded" Style="{StaticResource ResourceKey=ApplicationTitle}" />

That TextBlock now uses the 'ApplicationTitle' style in Typeography.xaml, which loads it's Foreground brush from the 'FlatGradientLightest' LinearGradientBrush in Brushes.xaml, which in turn loads two colors from Color resources in the Colours.xaml file.

Kinda cool right?

Hope that helps.

Stimul8d