none
Can I create DataTemplate Programatically?

    Question

  • Is it possible to create DataTemplate in code-behind?
    And I want to add a Grid object as content of this DataTemplate.
    Is this possible?
    Tuesday, June 05, 2007 12:01 PM

Answers

  • Hi,

    Yes it is possible to create a DataTemplate programmatically but it is not very elegant. Have a look at the following code:

    Code Snippet

    DataTemplate template = new DataTemplate();

    FrameworkElementFactory factory = new FrameworkElementFactory(typeof(StackPanel));

    template.VisualTree = factory;

    FrameworkElementFactory childFactory = new FrameworkElementFactory(typeof(Image));

    childFactory.SetBinding(Image.SourceProperty, new Binding("Machine.Thumbnail"));

    childFactory.SetValue(Image.WidthProperty, 170.0 ) ;

    childFactory.SetValue(Image.HeightProperty, 170.0 ) ;

    factory.AppendChild(childFactory);

    childFactory = new FrameworkElementFactory(typeof(Label));

    childFactory.SetBinding(Label.ContentProperty, new Binding("Machine.Descriiption"));

    childFactory.SetValue(Label.WidthProperty, 170.0);

    childFactory.SetValue(Label.HorizontalAlignmentProperty, HorizontalAlignment.Center);

    factory.AppendChild(childFactory);

     

    The following is taken from www.codeplex.com/Impilo

     

    Here I added a StackPanel. Each item included a data bound image and a description of the image. I also set some properties (ie. Width, Height, etc).

     

    Hope this helps...

     

    Rudi Grobler

    Tuesday, June 05, 2007 2:40 PM
  • something like this should work

    Code Snippet

    MemoryStream sr = null;

    ParserContext pc = null;

    string xaml = string.Empty;

    xaml = "<DataTemplate><TextBlock Text=\"Some Text\"/></DataTemplate>";

    sr = new MemoryStream(Encoding.ASCII.GetBytes(xaml));

    pc = new ParserContext();

    pc.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");

    pc.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");

    DataTemplate datatemplate = (DataTemplate)XamlReader.Load(sr, pc);

    this.Resources.Add("dt", datatemplate);

     

    Tuesday, June 05, 2007 1:03 PM

All replies

  •  

    per SDK '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.'

    • Proposed as answer by Alex Kven Saturday, August 27, 2011 2:02 PM
    • Unproposed as answer by Alex Kven Saturday, August 27, 2011 2:02 PM
    Tuesday, June 05, 2007 12:09 PM
  • Hi lee,

    can u provide me some code snippet for this?
    Tuesday, June 05, 2007 12:39 PM
  • something like this should work

    Code Snippet

    MemoryStream sr = null;

    ParserContext pc = null;

    string xaml = string.Empty;

    xaml = "<DataTemplate><TextBlock Text=\"Some Text\"/></DataTemplate>";

    sr = new MemoryStream(Encoding.ASCII.GetBytes(xaml));

    pc = new ParserContext();

    pc.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");

    pc.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");

    DataTemplate datatemplate = (DataTemplate)XamlReader.Load(sr, pc);

    this.Resources.Add("dt", datatemplate);

     

    Tuesday, June 05, 2007 1:03 PM
  • Hi,

    Yes it is possible to create a DataTemplate programmatically but it is not very elegant. Have a look at the following code:

    Code Snippet

    DataTemplate template = new DataTemplate();

    FrameworkElementFactory factory = new FrameworkElementFactory(typeof(StackPanel));

    template.VisualTree = factory;

    FrameworkElementFactory childFactory = new FrameworkElementFactory(typeof(Image));

    childFactory.SetBinding(Image.SourceProperty, new Binding("Machine.Thumbnail"));

    childFactory.SetValue(Image.WidthProperty, 170.0 ) ;

    childFactory.SetValue(Image.HeightProperty, 170.0 ) ;

    factory.AppendChild(childFactory);

    childFactory = new FrameworkElementFactory(typeof(Label));

    childFactory.SetBinding(Label.ContentProperty, new Binding("Machine.Descriiption"));

    childFactory.SetValue(Label.WidthProperty, 170.0);

    childFactory.SetValue(Label.HorizontalAlignmentProperty, HorizontalAlignment.Center);

    factory.AppendChild(childFactory);

     

    The following is taken from www.codeplex.com/Impilo

     

    Here I added a StackPanel. Each item included a data bound image and a description of the image. I also set some properties (ie. Width, Height, etc).

     

    Hope this helps...

     

    Rudi Grobler

    Tuesday, June 05, 2007 2:40 PM
  • Hi Rudi,
    Thanks for the reply. But I want to add an existing Grid object as a VisualTree.
    Is it possible?
    Wednesday, June 06, 2007 11:55 AM
  • Yes, just replace StackPanel with Grid. I just tested it and it worked...
    Wednesday, June 06, 2007 12:41 PM
  • FYI, SDK says FrameworkElementFactory is Deprecated
    Wednesday, June 06, 2007 1:28 PM

  • I had a question about the sample that you provided here.  I am trying to do something similar about creating a data template programmatically, and the data template that I am trying to create has a button with an OnClick event described. Whenever i try to use the code above to create the data template, the runtime throws an exception saying that I cannot include an event handler.  Is there a way around this problem ??
    Thanks
    -alok

    Monday, January 28, 2008 8:53 PM
  • Your example is excellent.  I am trying to build up a more complex structure, which I've found is easy if I do something like:

    WrapPanel wp = new WrapPanel();

    TextBlock tb = new TextBlock();

    tb.SetBinding(TextBlock.TextProperty, new Binding("HeaderText"));

    wp.Children.Add(tb)

    string xaml = XamlWriter.Save(wp);

    ... continue with your code.

     

    However, the binding to the text property is lost by teh XamlWriter.Save call.  Is there a way to get something like XamlWriter to generate that xaml text as well?

    Friday, April 04, 2008 10:17 PM
  • ok i followed this procedure , i am able to display images alright . i was doing this to add images to a gridviewcolumn . i was able to do it for a single image so all the rows in the column had the same image . please suggest how to go about it when i different images for each row of the column.
    Wednesday, May 13, 2009 8:35 AM
  • I am analyzing the purposed solution but got stuck at one point. I need to use a convertor as well in a data template. I tried but couldn't get thru. Steps are as follows - i have created a multi value converter & need to use that as a StaticResource. I am not sure if I am missing anything. Kindly suggest. 

    pc.XmlnsDictionary.Add("local", "clr-namespace:test");

    StringBuilder xamlString = new StringBuilder();
    xamlString.Append(@"<DataTemplate> ");

    xamlString.Append(@"<DataTemplate.Resources> ");
    xamlString.Append(@"<local:PatientConverter x:Key=""conv""/>");
    xamlString.Append(@"</DataTemplate.Resources> ");

    xamlString.Append(@"<Label Grid.Row=""3"" Grid.Column=""1"" >");
    xamlString.Append(@"<Label.Content>");

    xamlString.Append(@"<MultiBinding Converter=""{StaticResource conv}"">");

    xamlString.Append(@"<Binding Path=""FName"" />");
    xamlString.Append(@"<Binding Path=""LName"" />");
    xamlString.Append(@"</MultiBinding>");
    xamlString.Append(@"</Label.Content>");
    xamlString.Append(@"</Label>");

    Tuesday, May 10, 2011 4:38 AM
  • I have got the answer. Actually I was missing the assembly in the declaration of local namespace.

    pc.XmlnsDictionary.Add("local", "clr-namespace:test;assembly=test");

    even below approach is working

    xamlString.Append(@"<DataTemplate xmlns:local=""clr-namespace:test;assembly=test"" > ");

    xamlString.Append(@"<DataTemplate.Resources> <local:PatientConverter x:Key=""_conv""/> ");

    Thnx..

    Tuesday, May 10, 2011 5:14 AM
  • Thanks it really helpful..
    Friday, March 16, 2012 6:53 AM