Reputation: 79
I have a question that has me confused. I am studying for my MCP (test 70-511 Windows App. Dev. with .Net 4) and I am on the section of resources and changing resources in code. Here is a quote directly from the book (the Self Paced Training Kit):
If the object a resource refers to is changed in code, objects that use that resource behave differently, depending on how the resource is referenced. Resources referenced with the DynamicResource markup use the new object when the resource is changed in code. Objects that reference resources with the StaticResource markup continue to use the object they initially retrieved from the Resources collection and are unaware of the change.
With that said, one of the questions that they have you work through is is a XAML question. Here is the code for that question:
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<SolidColorBrush Color="Red" x:Key="ForegroundBrush" />
<SolidColorBrush Color="Blue" x:Key="BackgroundBrush" />
</Window.Resources>
<Grid>
<Button Background="{StaticResource BackgroundBrush}"
Foreground="{DynamicResource ForegroundBrush}" Height="23"
Margin="111,104,92,0" Name="Button1"
VerticalAlignment="Top">Button</Button>
</Grid>
</Window>
And the question is: What happens to the colors of the button when the following code is executed?
SolidColorBrush aBrush = new SolidColorBrush(Colors.Green);
this.Resources["ForegroundBrush"] = aBrush;
SolidColorBrush bBrush;
bBrush = (SolidColorBrush)this.Resources["BackgroundBrush"];
bBrush.Color = Colors.Black
Answer choices are:
The answer given by the book is 4 Both 2 and 3.
My dilemma/confusion is: if the book states that a dynamic resource will change to reflect the changes made in code, and the static resource will continue to use the object that they initially retrieved, then why does both the background and the foreground of the button change in the code/XAML example above? And I have tried it out and they do both change.
Any help would be appreciated.
Upvotes: 2
Views: 185
Reputation: 16648
Let's cut it into its 2 parts:
1) here the reference is changed:
SolidColorBrush aBrush = new SolidColorBrush(Colors.Green);
this.Resources["ForegroundBrush"] = aBrush;
2) here the reference stays the same, but you change a property (Color):
SolidColorBrush bBrush;
bBrush = (SolidColorBrush)this.Resources["BackgroundBrush"];
bBrush.Color = Colors.Black
Remember that behind the framework (WPF), there's regular code like you or I could write.
The behavior you see here is very much like how ObservableCollections behave:
If you use an ObservableCollection
as ItemsSource
of an ItemsControl
, and you then do:
myBoundObsCollection = new ObservableCollection<object>();
The binding won't refresh unless you raised PropertyChanged.
Here is a small sample, test to move the line:
Mycol = new ObservableCollection<string>();
Before/After InitializeComponent()
in the constructor and see what happens.
public partial class MainWindow : Window
{
public MainWindow()
{
this.DataContext = this;
Mycol = new ObservableCollection<string>();
InitializeComponent();
Mycol.Add("this");
Mycol.Add("is");
Mycol.Add("a");
Mycol.Add("test");
}
public ObservableCollection<string> Mycol { get; set; }
private void Button_Click(object sender, RoutedEventArgs e)
{
Mycol = new ObservableCollection<string>();
Mycol.Add("??");
}
}
And the XAML:
<Window x:Class="ObsColTest.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">
<StackPanel>
<ListBox ItemsSource="{Binding Mycol}" />
<Button Content="Click me!" Click="Button_Click"/>
</StackPanel>
</Window>
Then when you click the button, notice how the ListBox
doesn't update, even though the collection it's bound to radically changed!
But if you just modified the collection, the new rows would show up no matter if you raised PropertyChanged
or not on the Collection.
Same goes for the Color
property of your SolidColorBrush
.
DynamicResource works around this: on top of the fact that if you change any property of a resource it'll reflect on the UI, if you change the reference it'll reflect on the UI as well.
Just keep in mind that it makes DynamicResource (slightly?) less performant than StaticResource ;)
Upvotes: 1