Compartilhar via


Silverlight Tip of the Day #24: How to Apply a XAML Template to a Class

Let’s say you have a class where you want to declare elements via a XAML template instead of dynamically creating them.

For example, the XAML to declare an image and add it to a canvas would look like this:

 <Canvas x:Name="MyCanvas">
     <Image x:Name="MyImage" Source="Grass.png"></Image>
 </Canvas>

To do the same thing programmatically you would need to declare the following code:

 Image myImage = new Image();
 Uri uri = new Uri("Grass.png", UriKind.Relative);
 ImageSource imgSrc = new System.Windows.Media.Imaging.BitmapImage(uri);
 myImage.SetValue(Image.SourceProperty, imgSrc);

The way to do this via a template in a class is to first put the XAML into a string like this:

 private const string _contentTemplate
        = "<ControlTemplate xmlns=\"https://schemas.microsoft.com/winfx/2006/xaml/presentation\"" +
            "                  xmlns:x=\"https://schemas.microsoft.com/winfx/2006/xaml\">" +
            "<Image x:Name=\"MyImage\" Source=\"Grass.png\"></Image>" +
            "</ControlTemplate>";

Your class will need to inherit from Control:

 public class MyControl : Control

Now, in the constructor of your class you can load this template via the XamlReader.Load() method. You will need to add a using statement first to reference the namespace System.Windows.Markup;

 public MyControl()
 {
     Template = (ControlTemplate)XamlReader.Load(_contentTemplate);
     ApplyTemplate();
 }

ApplyTemplate() is where you can get the elements that are in declared in your XAML code. Override the function OnApplyTemplate like this:

 private _myImage;
  
 public override void OnApplyTemplate()
 {
     _myImage = (Image)GetTemplateChild("MyImage");
 }

Complete class:

 using System;
 using System.Net;
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Documents;
 using System.Windows.Ink;
 using System.Windows.Input;
 using System.Windows.Media;
 using System.Windows.Media.Animation;
 using System.Windows.Shapes;
 using System.Windows.Markup;
  
 namespace MapEditor
 {
     public class MyImage : Control
     {
         Image _myImage = null;
  
         private const string _contentTemplate
                = "<ControlTemplate xmlns=\"https://schemas.microsoft.com/winfx/2006/xaml/presentation\"" +
                    "                  xmlns:x=\"https://schemas.microsoft.com/winfx/2006/xaml\">" +
                    "<Image x:Name=\"MyImage\" Source=\"Grass.png\"></Image>" +
                    "</ControlTemplate>";
  
         public override void OnApplyTemplate()
         {
             _myImage = (Image)GetTemplateChild("MyImage");
         }
  
         public MyImage()
         {
             Template = (ControlTemplate)XamlReader.Load(_contentTemplate);
             ApplyTemplate();
         }
  
     }
 }

Thank you,

--Mike Snow

 Subscribe in a reader

Comments