I have a customized WPF control that is derived from UserControl. In the Resources section in my XAML file I have several templates and styles defined for the items that will be displayed on my custom control.
Here is a definition for one of my styles to draw an downward pointing arrow.
<Style x:Key="ArrowStyle" TargetType="Path">
<Setter Property="Margin" Value="4"/>
<Setter Property="Stretch" Value="Uniform"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Data" Value="M 0 0 L 5 5 L 10 0 Z"/>
<Setter Property="Fill" Value="{DynamicResource FormText}"/>
</Style>
So, I have a custom buttom object that is derived from button. Basically it is a small square button that displays the arrow. In my constructor for my custom button I have the following code.
Path Arrow = new Path();
Arrow.Style = TryFindResource("ArrowStyle") as Style;
However, the call to TryFindResource fails indicated that it cannot location the resource. If I move the defined style into App.xaml it find it, but not when it is a custom control resource.
What am I doing wrong or missing?
Update
The custom button that I am calling TryFindResource for does reside on the custom user control. However, since I am calling TryFindResource in the constructor of the custom button it will not actually reside on the custom user control at the time TryFindResource is called. After the custom button is created it will be added to the custom user control. Perhaps there is a different way or place to put the TryFindResource so that it is called after the button belongs to the control.
TryFindResource traverses the logical tree upward, to the parent element until the root element is reached.
Then application resources are checked. That is the one you put in the second try, and worked because it was found there.
So when you say "TryFindResource("ArrowStyle"), it searches the arrow style on its parent elements up to its window resources and then application resources (global resources). When you call it from your custom button object, it can't find it because your ArrowStyle resource do not satisfy the conditions above.
You need to call it on your "customized WPF control that is derived from UserControl" or descendants of it.
I think if you can't make it work just move it to application resources or add a resource dictionary to your application resources with all global resources (styles):
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="....Your resources.xaml"/>
<ResourceDictionary Source="....Your resources.xaml"/>
<!-- Place further resources here -->
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
I'm assuming that when you say you have the styles defined in the resources section of your XAML, then that is in the window or user control in which the button resides.
To find a resource there from the button, you must walk up the logical tree to get the parent and call TryFindResource from it. Otherwise, you're only alternatives are to put the style with the button or in the App.xaml.
Usually a better place to load Resources is in an OnApplyTemplate override or a Loaded event handler instead of the constructor. This will behave more like what happens when you add a resource reference in XAML: the control is constructed and added into the visual tree, and then tries to resolve resources from anywhere they might be declared in any parent objects' resources. As you correctly stated, when the constructor runs your button has not yet been added to the parent control and therefore can't yet see the Style.