How to set Control Template in code?
Asked Answered
C

3

38

I have this in XAML

<ControlTemplate TargetType="{x:Type Button}">
    <Image ...>
</ControlTemplate>

I want to achieve same in C# code. How can I achieve this?

ControlTemplate ct = new ControlTemplate();..
Image img = new Image();..

Now how to assign this Image to Control template? Can we do this or Am I missing any concept here?

Chance answered 22/4, 2011 at 12:36 Comment(0)
S
36

Creating template in codebehind is not a good idea, in theory one would do this by defining the ControlTemplate.VisualTree which is a FrameworkElementFactory.

ControlTemplate template = new ControlTemplate(typeof(Button));
var image = new FrameworkElementFactory(typeof(Image));
template.VisualTree = image;

Assigning properties is very roundabout since you need to use SetValue and SetBinding:

image.SetValue(Image.SourceProperty, ...);

Also, about the (previously) accepted answer and the stuff quoted:

Setting the ControlTemplate programmatically is just like using XAML because we have to use the XamlReader class.

That statement is just wrong, we do not "have to".


If i assign templates at run time i define them as a resource which i can load if i need it.


Edit: According to the documentation FrameworkElementFactory is deprecated:

This class is a deprecated way to programmatically create templates, which are subclasses of FrameworkTemplate such as ControlTemplate or DataTemplate; not all of the template functionality is available when you create a template using this class. The recommended way to programmatically create a template is to load XAML from a string or a memory stream using the Load method of the XamlReader class.

I wonder if this recommendation is such a good idea. Personally i would still go with defining the template as a resource in XAML if i can avoid doing it with strings and the XamlReader.

Spanner answered 22/4, 2011 at 13:8 Comment(4)
Thanks worked perfectly... I know it is not a good idea but I have no choice in one particular caseChance
Well, i just quote the text form the site i found.. And what wrong with using XamlReader.Parse?Forcemeat
@Ai_boy: It's just parsing of XAML, which is both unnecessary and not something i would recommend, if you have static XAML it is better to create it as a XAML resource instead of hacking a XML string into code-behind.Spanner
@h-b Ow, i get it.. and i think that "dinamic" Xaml is not for buisness apps, so.. both approches is like "dirty hack" to me.. anyway tnx for your answer.Forcemeat
F
25

http://www.eggheadcafe.com/sample-code/SilverlightWPFandXAML/73fdb6a2-6044-4c43-8766-afa12618ddc1/set-controltemplate-programmatically.aspx

Setting the ControlTemplate programmatically is just like using XAML because we have to use the XamlReader class. For example, here is the code to set a button's template, assuming that we want to set a button's template after it is loaded.

private void Button_Loaded(object sender, RoutedEventArgs e) {
    var button = sender as Button;
    string template =
        "<ControlTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
            TargetType=\"Button\">" +
            "<Border>" +
                 "<ContentPresenter/>" +
            "</Border>" +
        "</ControlTemplate>";
    button.Template = (ControlTemplate)XamlReader.Parse(template);
}

Since we used a string for specifying the XAML code for the template, we can use the XamlReader's Parse method. The XamlReader also has a Load method, which is primarily used for streams or XAML or XML readers. Notice that we have to include the XML namespace http://schemas.microsoft.com/winfx/2006/xaml/presentation because the ControlTemplate, Border, and other controls we need are defined there. If we did not include it, we'll encounter a runtime exception. Basically, we have to put the namespaces needed by the template.

Forcemeat answered 22/4, 2011 at 12:53 Comment(0)
H
0

If you need to change the button image only then you can do one thing.

  1. Create a dependency property which will represent when you want to change the image (a bool) or may be you can create an enum which has all possible images say
  2. Enum Images { Image1 = 0, Image2 = 1, Image2 = 3}. Create a dependency property "CurrentButtonImage" of this type which will be associated with button.

Now in XAML use this in button template

On property Change of CurrentButtonImage update the image of button (in code behind) using

CurrentImagePropertyChangedhandler(....,...)  
{  
    switch(CurrentButtonImage)  
    {  
        case "Image1" :  
          this._ButtonImage.Fill = (DrawingBrush)csd.FindResource("Image1DrawingBrush");
          break;
    }
}
Hanforrd answered 22/4, 2011 at 12:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.