From this page, I read:
If your application uses custom controls and defines resources in a ResourceDictionary (or XAML Resources node), it is recommended that you either define the resources at the Application or Window object level, or define them in the default theme for the custom controls. Defining resources in a custom control's ResourceDictionary imposes a performance impact for every instance of that control.
Ok... now, I have a UserControl that defines the following resources:
<UserControl ...>
<UserControl.Resources>
<Namespace:ImagesConverter x:Key="ImagesConverter" ...
<Storyboard x:Key="AnimationHide" ...
</UserControl.Resources>
So, because of the fact I'm creating not less than 100 instances of them at runtime, as the MSDN tutorial says, it would be better to move those resources ad MainWindow or App level. Where's the best location to move them to? MainWindow level, App level or resource file? And why?
And then... how can I use them from their new location? Let's say I have this code inside my UserControl:
m_AnimationHide = (Storyboard)Resources["AnimationHide"];
How should I modify it to reflect those changes? And how should I modify the following UserControl XAML snippet instead?
Source="{Binding Source={x:Static Properties:Resources.MyImage}, Converter={StaticResource ImagesConverter}}"
Personally, I prefer to use App.xaml
or seperate ResourceDictionary
over adding them all to the Window.Resources
, this eliminates clutter in your Window
xaml.
This also allows you to easily create Themes
for you application as you have them all in one place, so you can copy your existing ResourceDictionary
change brush colors etc, the you can choose what ResourceDictionary
you want to load and and easily change the entire apperance of your application.
As for accessing the Resouces
in your Usercontrol
there is no difference on the xaml side, you will continue to use {StaticResource resourceKey}
as when you call a StaticResource
it searches though the Resource
hierarchy to find the Resource
.
So if you move you resource from UserControl.Resources
to Window.Resources
or Application.Resources
you don't need to change anything in your xaml code that is accessing though {StaticResource resourceKey}
.
As for access in code behind you will use FindResource("resourceKey")
instead of Resources["resourceKey"]
as FindResource
will search the hierarchy for the Resource
like the StaticResource
does in xaml.
Example:
m_AnimationHide = (Storyboard)FindResource("AnimationHide");
If you want to modify any of these Resources in a specific control and they are frozen you can just create a copy for that instance
Example
var animation = FindResource("AnimationHide") as Storyboard;
m_AnimationHide = animation.Clone();
m_AnimationHide.Completed += m_AnimationHide_Completed;
You can also set x:Shared="false"
this will return a new instance of the animation each time from the Resources, this will save copy/pasting the same animation througout your application if you have a complex Resource that you need to change values in.
<Storyboard x:Key="AnimationHide" x:Shared="false" />
Then you will be able to modify the resource locally.