-
- nvonhertzen
- Posts: 2
- Joined:
ResourceDictionary.MergedDictionaries and StaticResources
I am having some issues getting StaticResources working with ResourceDictionary.MergedDictionaries when used outside of application resources.
Given the following xaml:
I was expecting B.xaml to be able to resolve a StaticResource defined in A.xaml, because it is above it in the tree and it is not defined in an adjacent MergedDictionary. This is however not the case, and stepping through the code it appears that it stops looking through the tree in ResourceDictionary::FindNodeResource when mOwner is ResourceDictionary.MergedDictionaries because DynamicCast<FrameworkElement*>(mOwner) is nullptr for UICollection<ResourceDictionary>.
Is this the expected behavior? I.e. is B.xaml not able to statically resolve a resource defined earlier in the tree? Updating the DynamicCast<FrameworkElement*>(mOwner) to DynamicCast<IUITreeNode*>(mOwner) fixes the issue, but it isn't immediately clear to me are there some drawbacks/reasons why it was using FrameworkElement* specifically instead of the IUITreeNode* interface?
Is there some other alternative to how to set this up? We are moving away from using global app resources because we have distinct UI Views that should not be mixing their resources, so we are trying to move all of them to the top of the view. Many of our ResourceDictionaries reference resources from other ResourceDictionaries, and it seems that looking up adjacent merged dictionaries isn't something that works in WPF either (hence the nested setup in this example). We'd want to avoid switching to using DynamicResources for many cases due to unnecessary perf hit, but also because not all of the locations support DynamicResourceExpression either.
Given the following xaml:
Code: Select all
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="A.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Viewbox>
<Grid>
<Grid.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="B.xaml" />
<ResourceDictionary Source="..." />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Grid.Resources>
</Grid>
</Viewbox>Is this the expected behavior? I.e. is B.xaml not able to statically resolve a resource defined earlier in the tree? Updating the DynamicCast<FrameworkElement*>(mOwner) to DynamicCast<IUITreeNode*>(mOwner) fixes the issue, but it isn't immediately clear to me are there some drawbacks/reasons why it was using FrameworkElement* specifically instead of the IUITreeNode* interface?
Is there some other alternative to how to set this up? We are moving away from using global app resources because we have distinct UI Views that should not be mixing their resources, so we are trying to move all of them to the top of the view. Many of our ResourceDictionaries reference resources from other ResourceDictionaries, and it seems that looking up adjacent merged dictionaries isn't something that works in WPF either (hence the nested setup in this example). We'd want to avoid switching to using DynamicResources for many cases due to unnecessary perf hit, but also because not all of the locations support DynamicResourceExpression either.
-
-
sfernandez
Site Admin
- Posts: 3363
- Joined:
Re: ResourceDictionary.MergedDictionaries and StaticResources
Hi,
Yes, that is the expected behavior. StaticResources inside a dictionary can only be resolved against resources declared before inside that dictionary or any merged dictionary in that same dictionary, and of course resources available in the Application Resources. We can't change that behavior because it is a deviation from WPF and Blend.
In your case, B would need to merge A to be able to access its resources. My recommendation is that you place common resources in the ApplicationResources, and if they are only common to a few views, then merge only the necessary ones in the resource dictionaries of those views.
Yes, that is the expected behavior. StaticResources inside a dictionary can only be resolved against resources declared before inside that dictionary or any merged dictionary in that same dictionary, and of course resources available in the Application Resources. We can't change that behavior because it is a deviation from WPF and Blend.
In your case, B would need to merge A to be able to access its resources. My recommendation is that you place common resources in the ApplicationResources, and if they are only common to a few views, then merge only the necessary ones in the resource dictionaries of those views.
Who is online
Users browsing this forum: Bing [Bot] and 3 guests