This is a mirror of official site:

Creating WPF Data Templates in Code: The Right Way

| Wednesday, August 22, 2012

The Right Way

The MSDN article for FrameworkElementFactory then goes on to say:

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.

The trouble is, the XAML parser they give you in .NET framework is not quite the same as XAML parser that comes with VIsual Studio. In particular, you need to apply some tricks in order to deal with C# namespaces. The resulting code looks as follows:

DataTemplate CreateTemplate(Type viewModelType, Type viewType)
    const string xamlTemplate = "<DataTemplate DataType=\"{{x:Type vm:{0}}}\"><v:{1} /></DataTemplate>";
    var xaml = String.Format(xamlTemplate, viewModelType.Name, viewType.Name, viewModelType.Namespace, viewType.Namespace);

    var context = new ParserContext();

    context.XamlTypeMapper = new XamlTypeMapper(new string[0]);
    context.XamlTypeMapper.AddMappingProcessingInstruction("vm", viewModelType.Namespace, viewModelType.Assembly.FullName);
    context.XamlTypeMapper.AddMappingProcessingInstruction("v", viewType.Namespace, viewType.Assembly.FullName);

    context.XmlnsDictionary.Add("", "");
    context.XmlnsDictionary.Add("x", "");
    context.XmlnsDictionary.Add("vm", "vm");
    context.XmlnsDictionary.Add("v", "v");

    var template = (DataTemplate)XamlReader.Parse(xaml, context);
    return template;

The bad news is that this code is much more verbose and awkward then the naive code. The good news is that this code works better. In particular, it has no problem with forward bindings.

Another bad thing about the new way of creating templates is that both view and view model classes must be public in .NET 3.5. If they are not, you'll get a runtime exception when parsing the XAML that says they should be. .NET 4 does not have this limitation: all classes may be internal.

Registering Data Template with the Application

In order to create visual objects using your data tempalte, WPF must somehow know about it. You make your template globally available by adding it to the application resources:

var key = template.DataTemplateKey;
Application.Current.Resources.Add(key, template);

Read more: Codeproject
QR: Inline image 1

Posted via email from Jasper-net