Sdílené ResourceDictionary a výchozí hodnoty v XAMLu


Čím více se rozrůstají styly definované v XAMLu a vůbec další data v Resources, tím více je nutné různé opakující se hodnoty centralizovat a vytvářet sdílené ResourceDictionary. U stylů pro začátek stačí vyčlenit barvy a rozměry, resp. velikosti a zarovnání…

Hlavně záleží na velikosti projektu a pro ty vetší je vhodné rovnou tyto hodnoty definovat samostatně. V podstatě jde o to, že hodnoty, které se často opakují (klidně 2x), se vyčlení pod klíčem do vlastního ResourceDictionary, který se může vkládat do dalších ResourceDictionary nebo přímo do Resources GUI prvků. Případná změna hodnoty je pak velmi jednoduchá a projeví se na všech místech. Také je vhodné hned promyslet a pečlivě pojmenovávat klíče, např. pokud se jedná o styl, tak za název přidávat příponu “Style”, pro DataTemplate zase “DataTemplate” apod., takže např. pro výchozí barvu popředí by byl vhodný klíč “DefaultForegroundColor”.

Základní, sdílený ResourceDictionary “Shared.xaml” může vypadat takto:


<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:System="clr-namespace:System;assembly=mscorlib">

  <!-- Colors -->
  <Color x:Key="DefaultBackgroundColor">#FFFFFFFF</Color>
  <SolidColorBrush x:Key="DefaultBackgroundColorBrush" Color="{DynamicResource DefaultBackgroundColor}" />
  <Color x:Key="DefaultForegroundColor">#FF000000</Color>
  <SolidColorBrush x:Key="DefaultForegroundColorBrush" Color="{DynamicResource DefaultForegroundColor}" />
  <Color x:Key="DefaultBorderColor">#FFFF0000</Color>
  <SolidColorBrush x:Key="DefaultBorderColorBrush" Color="{DynamicResource DefaultBorderColor}" />

  <!-- Sizes -->
  <Thickness x:Key="DefaultBorderThickness">1</Thickness>
  <Thickness x:Key="DefaultMarginThickness">2</Thickness>
  <Thickness x:Key="DefaultPaddingThickness">3</Thickness>
  <System:Double x:Key="DefaultWidthDouble">100</System:Double>
  <System:Double x:Key="DefaultHeightDouble">25</System:Double>

  <!-- Alignments -->
  <HorizontalAlignment x:Key="DefaultHorizontalAlignment">Left</HorizontalAlignment>
  <VerticalAlignment x:Key="DefaultVerticalAlignment">Center</VerticalAlignment>

</ResourceDictionary>

ResourceDictionary “Generic.xaml” se styly jednotlivých kontrolů (, který využívá ten sdílený):


<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="Shared.xaml" />
  </ResourceDictionary.MergedDictionaries>

  <!-- TextBox -->
  <Style TargetType="TextBox">
    <Setter Property="Background" Value="{DynamicResource DefaultBackgroundColor}" />
    <Setter Property="Foreground" Value="{DynamicResource DefaultForegroundColor}" />
    <Setter Property="BorderBrush" Value="{DynamicResource DefaultBorderColor}" />
    <Setter Property="BorderThickness" Value="{DynamicResource DefaultBorderThickness}" />
    <Setter Property="Margin" Value="{DynamicResource DefaultMarginThickness}" />
    <Setter Property="Padding" Value="{DynamicResource DefaultPaddingThickness}" />
    <Setter Property="Width" Value="{DynamicResource DefaultWidthDouble}" />
    <Setter Property="Height" Value="{DynamicResource DefaultHeightDouble}" />
    <Setter Property="HorizontalAlignment" Value="{DynamicResource DefaultHorizontalAlignment}" />
    <Setter Property="VerticalAlignment" Value="{DynamicResource DefaultVerticalAlignment}" />
  </Style>
  
  <!-- PasswordBox -->
  <Style TargetType="PasswordBox">
    <Setter Property="Background" Value="{DynamicResource DefaultBackgroundColor}" />
    <Setter Property="Foreground" Value="{DynamicResource DefaultForegroundColor}" />
    <Setter Property="BorderBrush" Value="{DynamicResource DefaultBorderColor}" />
    <Setter Property="BorderThickness" Value="{DynamicResource DefaultBorderThickness}" />
    <Setter Property="Margin" Value="{DynamicResource DefaultMarginThickness}" />
    <Setter Property="Padding" Value="{DynamicResource DefaultPaddingThickness}" />
    <Setter Property="Width" Value="{DynamicResource DefaultWidthDouble}" />
    <Setter Property="Height" Value="{DynamicResource DefaultHeightDouble}" />
    <Setter Property="HorizontalAlignment" Value="{DynamicResource DefaultHorizontalAlignment}" />
    <Setter Property="VerticalAlignment" Value="{DynamicResource DefaultVerticalAlignment}" />
  </Style>
  
</ResourceDictionary>

A definice pro celou aplikaci v “App.xaml”:


<Application x:Class="ResourceDictionarySample.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
  <Application.Resources>
    <ResourceDictionary Source="/Themes/Generic.xaml" />
  </Application.Resources>
</Application>

TIP: všimněte si, že sdílené hodnoty jsou zde v Setterech stylů definovány jako DynamicResource, což má za následek to, že v případě výměny MergedDictionaries se změny hned projeví…

A výsledek pro pořádek vypadá v tomto případě takto:

ResourceDictionary Sample

, , , , , ,

Komentáře jsou uzavřeny.