asusralis
Topic Author
Posts: 142
Joined: 30 Jul 2018, 05:03

Unable to find resource in an element.

15 May 2020, 18:08

I'm creating a custom control and its style. In the code behind I have this:
Loaded += (s, e) =>
            {
                Grid root = (Grid)FindName("Root");

                _tLeft = (ImageBrush)root.FindResource("TLeft");
                ...
            };
And in the ControlTemplate:
ControlTemplate TargetType="{x:Type local:NineSliceControl}">
                    <Grid x:Name="Root">
                        <Grid.Resources>
                            <Style TargetType="Rectangle">
                                <Setter Property="SnapsToDevicePixels" Value="True" />
                                <Setter Property="RenderOptions.BitmapScalingMode" Value="NearestNeighbor" />
                            </Style>
                            <ImageBrush
                                x:Key="TLeft"
                                ImageSource="{TemplateBinding ImageSource}"
                                ViewboxUnits="Absolute" />
                              ...
                        </Grid.Resources>
               </Grid>
                </ControlTemplate>
                        
On Loaded I'm able to find the root grid, but it seems the grid doesn't have any of the resources. I'm pretty sure it's using that style because it is finding the root grid. I'm defining my style in my main resources file.
 
User avatar
sfernandez
Site Admin
Posts: 2983
Joined: 22 Dec 2011, 19:20

Re: Unable to find resource in an element.

22 May 2020, 16:11

Hi,

Elements of the template visual tree cannot be get using FindName on the Control, because template elements have its own NameScope.
Template elements can be accessed using Template.FindName(name, templatedParent) instead:
Loaded += (s, e) =>
{
    Grid root = (Grid)Template.FindName("Root", this);

    _tLeft = (ImageBrush)root.FindResource("TLeft");
    ...
};
I'm assuming here that this is the code behind of the custom control and that Template property is not null.

A better approach could be to define those resources in the ControlTemplate.Resources property, so you don't need to access the root of the template visual tree:
<ControlTemplate TargetType="{x:Type local:NineSliceControl}">
  <ControlTemplate.Resources>
    <ImageBrush
                x:Key="TLeft"
                ImageSource="{TemplateBinding ImageSource}"
                ViewboxUnits="Absolute" />
    ...
  </ControlTemplate.Resources>
  ...
</ControlTemplate>
Loaded += (s, e) =>
{
    _tLeft = (ImageBrush)Template.FindResource("TLeft");
    ...
};

Who is online

Users browsing this forum: No registered users and 53 guests