16

I have a Silverlight controls assembly, called "MySilverlightControls". Several folders down into that assembly I have a class which extends a grid column from a third party vendor, let's call it "MyImageColumn.cs".

I have also created a resource dictionary called Generic.xaml, this is situated in the Themes folder of the assembly. In that resource dictionary i have defined a ControlTemplate called MyImageColumnTemplate:

<ControlTemplate x:Name="MyImageColumnTemplate" >
    <Grid Margin="8,8,4,4" MaxHeight="32" MaxWidth="32">
        <Grid.Resources>
            <localGrid:StatusColumnImageConverter x:Key="ImageContentConverter"/>
        </Grid.Resources>
        <Border Margin="5,5,0,0" Background="Black" Opacity="0.15" CornerRadius="5" />
        <Border Background="#FF6E6E6E" CornerRadius="4,4,4,4" Padding="4" Margin="0,0,5,5">
            <Border Background="White" CornerRadius="2,2,2,2" Padding="3">
                <Image Source="{Binding EditValue, Converter={StaticResource ImageContentConverter}}" Stretch="Uniform"/>
            </Border>
        </Border>
    </Grid>
</ControlTemplate>

My question is: from MyImageColumn, how can I programmatically reference/load this control template so I can assign it to a property on the column? I would expect to be using a syntax similar to this:

ControlTemplate ct = (ControlTemplate)Application.Current.Resources["MyImageColumnTemplate"];

but this always returns null. When I load the assembly up in Reflector, I see that the Generic.xaml file is there, the name of the resource is MySilverlightControls.g.resources, and the path within that is themes/generic.xaml.

How exactly can I get to the individual items in this resource dictionary?

Vikrant
  • 4,920
  • 17
  • 48
  • 72
slugster
  • 49,403
  • 14
  • 95
  • 145

1 Answers1

30

Got it solved.

I needed to:

  • load my resource dictionary
  • merge it with the application's resources
  • load my control template from the application resource

As part of loading the resource dictionary, i also had to register the pack URI scheme. I then had to deal with some crazy COM based exceptions due to slight errors with my xaml. I also had to move my xaml into a separate resource dictionary file, trying to do it through generic.xaml kept throwing errors (even though the xaml was faultless and could be loaded fine using the newly created resource dictionary file). So, simplifying it down, this was the code:

if (!UriParser.IsKnownScheme("pack"))
    UriParser.Register(new GenericUriParser(GenericUriParserOptions.GenericAuthority), "pack", -1);

ResourceDictionary dict = new ResourceDictionary();
Uri uri = new Uri("/MySilverlightControls;component/themes/Dictionary1.xaml", UriKind.Relative);
dict.Source = uri;
Application.Current.Resources.MergedDictionaries.Add(dict);
ControlTemplate ct = (ControlTemplate)Application.Current.Resources["MyImageColumnTemplate"];

I have posted the full details for this solution in this blog post.

har07
  • 88,338
  • 12
  • 84
  • 137
slugster
  • 49,403
  • 14
  • 95
  • 145
  • 2
    Saved me a lot of time. Thanks so much for the blog post. Great job. – captonssj May 07 '13 at 23:04
  • 2
    Just a note on why @slugster did those first two lines. The `pack` Uri style is not loaded and registered by default, causing `Uri uri = new Uri(any pack Uri style string);` to throw an exception. This way of getting it registered is less intrusive to your code than waiting until after you have created your first `FrameworkElement` before allowing yourself to use the `pack` Uri. – Jesse Chisholm Oct 08 '15 at 22:39