ResourceDictionary.MergedDictionaries and StaticResources
Posted: 25 May 2022, 10:09
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.