iAteABug_And_iLiked_it
iAteABug_And_iLiked_it

Reputation: 3795

Set control Background color using Dynamic Resource in WPF?

This is my XAML

<Grid.Resources>
            <SolidColorBrush x:Key="DynamicBG"/>
</Grid.Resources>
<Label name="MyLabel" Content="Hello" Background="{DynamicResource DynamicBG} />

So I have two questions:

Q1: How do I go about setting the DynamicBG key value to Red in my code now? (When the window loads, I'd like to set it to red)

Q2: Is this how dynamic resources are supposed to be used?

Thank you

Upvotes: 25

Views: 50645

Answers (3)

Anatoliy Nikolaev
Anatoliy Nikolaev

Reputation: 22702

To gain access to the Resource of the code must identify them in the file App.xaml:

<Application.Resources>
    <SolidColorBrush x:Key="DynamicBG" />
</Application.Resources>

XAML example

<Grid>       
    <Label Name="MyLabel" 
           Content="Hello" 
           Background="{DynamicResource DynamicBG}" />

    <Button Content="Change color"
            Width="100" 
            Height="30" 
            Click="Button_Click" />
</Grid>

The Resource can be changed in code line of the form:

Application.Current.Resources["MyResource"] = MyNewValue;

Example:

Code behind

// using ContentRendered event
private void Window_ContentRendered(object sender, EventArgs e)
{
    SolidColorBrush MyBrush = Brushes.Aquamarine;

    // Set the value
    Application.Current.Resources["DynamicBG"] = MyBrush;         
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    SolidColorBrush MyBrush = Brushes.CadetBlue;

    // Set the value
    Application.Current.Resources["DynamicBG"] = MyBrush;
}

Principle, DynamicResources were designed, so they can be changed. Where to change - it is the task of the developer. In the case of Color, it is one of the most common methods. See the MSDN, for more information.

P. S. I recommend using App.xaml, because there have been cases where a StaticResource has been used successfully, but not DynamicResource (resources are placed in the Window.Resources). But after moving the resource in App.xaml, everything started to work.

Upvotes: 24

Anton Tykhyy
Anton Tykhyy

Reputation: 20056

A2: no. To do what you are doing, it is better to use data binding. Have a property in your viewmodel indicating whether it's 'loaded', then bind the background to it with a suitable converter, or use a trigger. (If it's actually UI that is loading, add the property to the window.) Dynamic resources are used for theming and with templates, in the rare cases when a StaticResource lookup happens too early.

Upvotes: 3

kmatyaszek
kmatyaszek

Reputation: 19296

A1: You should move "DynamicBG" to window resource and after that you can use Resources property in Loaded event handler:

XAML:

<Window x:Class="MyLabelDynamicResource.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        Loaded="Window_Loaded">
    <Window.Resources>
        <SolidColorBrush x:Key="DynamicBG"/>
    </Window.Resources>
    <Grid>    
        <Label Name="MyLabel" Content="Hello" Background="{DynamicResource DynamicBG}" />
    </Grid>
</Window>

Code-behind:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        this.Resources["DynamicBG"] = new SolidColorBrush(Colors.Red);
    }      
}

A2: You should use dynamic resources when you want to change property in runtime.

Upvotes: 8

Related Questions