1

I currently have a set of Rectangles throughout my application that I define in XAML like so;

<Rectangle Fill="LightBlue"/>

At the moment I have maybe < 10 Rectangles so changing the Colour of a Rectangle is not too much of an issue.

However, as my App grows, I will no doubt have many, many more Rectangles and if it is decided that their colour needs to change, I can see that scalability will be a big issue.

What would be the most efficient way of storing the Background of a Rectangle so that I could change it in one place to change all of the Rectangles in my program?

This would also extend to a style of say a TextBox. If I wanted to set one custom style for every TextBox throughout the app, what would be a scalable approach to this?

Taterhead
  • 5,763
  • 4
  • 31
  • 40
CBreeze
  • 2,925
  • 4
  • 38
  • 93
  • You can use [style inheritance](http://stackoverflow.com/q/11581475/1997232). Then defining a new style with some key based on default one will allow you: 1) create control of that style (with different `Fill` property) 2) create new style based on that (and change something in it, e.g. set `Margin`) 3) change default style (one without key). Changing of either will then automatically change appearance of control using that style. – Sinatr Mar 21 '16 at 14:32

3 Answers3

6

Try using a Style:

Insert it in your app.xaml to affect all Rectangles in all Windows.

<Application.Resources>
    <!-- Use the Color ala "Lorentz Vedeler" to make it reusable -->
    <SolidColorBrush x:Key="myRectangleBrush" Color="LightBlue" />
    <!-- Apply it in Style -->
    <Style TargetType="Rectangle">
        <Setter Property="Fill" Value="{StaticResource myRectangleBrush}" />
    </Style>
</Application.Resources>

OR

For just all Rectangles in the current Window.

<Window.Resources>
    <Style TargetType="Rectangle">
        <Setter Property="Fill" Value="LightBlue" />
    </Style>
</Window.Resources>

NOTE:

Do not specify x:Key since then you need to set the Style for every Rectangle you want to apply it to. TargetType will apply it for all UI-Elements of that Type.

 <Window.Resources>
    <Style TargetType="Rectangle" x:Key="RectStyle">
        <Setter Property="Fill" Value="LightBlue" />
    </Style>
</Window.Resources>

<Rectangle Style="{StaticResource RectStyle}" />
Felix D.
  • 4,811
  • 8
  • 38
  • 72
2

I'd define the color in your application resources in the app.xaml-file:

<Application.Resources>
    <SolidColorBrush x:Key="myRectangleBrush" Color="#deadb33f" />
</Application.Resources>

Then you can use it like this:

<Rectangle Fill="{StaticResource myRectangleBrush}" />

The advantage of this is that you could reuse the color for many kinds of controls. If your company has a color profile that you use in your rectangles and also for some lines, then marketing decides to change your company color to a different shade. You could change it for all rectangles and lines at the same time.

Default styles for controls are made by adding a style to application resources with a target type attribute and without a key attribute.

Lorentz Vedeler
  • 5,101
  • 2
  • 29
  • 40
  • 1
    I would actually combine this answer and FeDe's in the case of making it easier to propagate branding. In that I would use the brush resource inside the style template. This way if something needs changed like the brush name you don't have to do it at every single instance and just at the template level. Just two cents. – Chris W. Mar 21 '16 at 14:47
  • @ChrisW. That is definetly the way to go – Lorentz Vedeler Mar 21 '16 at 14:50
0

In order to change the themes of WPF Window dynamically, you can create several ResourceDictionary files and place then for e.g. in the folder Themes:

Listing 1. ResourceDictionary file (XAML)

<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">
... SAMPLE STYLES
<Style TargetType="Rectangle">
    <Setter Property="Fill" Value="Green" />
</Style>
<Style TargetType="TextBox">
   <Setter Property="Background" Value="Green"/>
</Style>

</ResourceDictionary>

then refer to the default theme (e.g. Blue.xaml) in the main Window XAML

Listing 2. set default theme in Window XAML

<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="Themes\Blue.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Window.Resources>

and dynamically switch between the theme (for e.g. to "Green.xaml) using Window's Control event handler (e.g. Button.Click event) in C# code behind module:

Listing 3. Dynamically set WPF Window Theme ResourceDictionary

/// <summary>
/// Dynamically set WPF Window Theme resource dictionary
/// </summary>
private void SelectGreenTheme()
{
    // prefix to the relative Uri for Theme resources (xaml file)
    string _prefix = String.Concat(typeof(App).Namespace, ";component/");

    // clear all resource dictionaries in this window
    // Note: on app level use: Application.Current.Resources.MergedDictionaries.Clear();
    this.Resources.MergedDictionaries.Clear();

    // add resource theme dictionary to this window
    // Note: on app level use: Application.Current.Resources.MergedDictionaries.Add
    this.Resources.MergedDictionaries.Add
    (
        new ResourceDictionary { Source = new Uri(String.Concat(_prefix + "Themes\Green.xaml, UriKind.Relative) }
    );
}
Alexander Bell
  • 7,842
  • 3
  • 26
  • 42