在后面的代码中创建DataTemplate

MYR*_*RAO 22 c# dynamic code-behind datatemplate

如何以编程方式向datatemplates添加控件?

例如.下面我创建了TextBlock和DataTemplate.

TextBlock text = new TextBlock();
DataTemplate template = new DataTemplate();
Run Code Online (Sandbox Code Playgroud)

现在我需要将TextBlock添加到DataTemplate.怎么做到这一点?

我知道后面的代码中还有其他addind数据模板的方法1.在XAML中创建数据模板并将其加载到后面的代码上2.使用XamlParser创建和添加

但我需要按照我在示例中展示的方式来做.

需要一些帮助.

Rus*_*ngs 32

虽然Archedius的方法有效,但官方它已被弃用,而是建议以编程方式创建模板的方法是使用XamlReader类的Load方法从字符串或内存流加载XAML,如下所示...

public DataTemplate Create(Type type)
{
    StringReader stringReader = new StringReader(
    @"<DataTemplate 
        xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""> 
            <" + type.Name + @" Text=""{Binding " + ShowColumn + @"}""/> 
        </DataTemplate>");
    XmlReader xmlReader = XmlReader.Create(stringReader);
    return XamlReader.Load(xmlReader) as DataTemplate;
}
Run Code Online (Sandbox Code Playgroud)

官方专线来自msdn:http://msdn.microsoft.com/en-us/library/system.windows.frameworkelementfactory.aspx

Fredrik Hedblad的帖子中的代码示例:XamlReader生成DataTemplate的问题

  • 与其他选项可能已经过时一样,这是一个“非常”不方便的方法,不仅它几乎不提供静态错误检查,而且生成的错误消息是神秘的(例如第 5 行位置 27 处的意外字符 0x20),而且它还意味着您无权访问项目资源。恕我直言,远离这个,只需要最简单的模板。 (4认同)
  • 使用System.Windows.Markup中的XamlReader而不是System.Xaml (3认同)

Arc*_*ius 31

您首先要声明一个DataTemplate:

DataTemplate template = new DataTemplate { DataType = typeof(< Type of the object the template refers>) };
Run Code Online (Sandbox Code Playgroud)

然后以这种方式声明像StackPanel这样的布局面板

FrameworkElementFactory stackPanelFactory = new FrameworkElementFactory(typeof(StackPanel));
stackPanelFactory.SetValue(StackPanel.OrientationProperty, Orientation.Vertical);
Run Code Online (Sandbox Code Playgroud)

最后附上TextBlock片段:

FrameworkElementFactory title = new FrameworkElementFactory(typeof(TextBlock));
title.SetBinding(TextBlock.TextProperty, new Binding("< name of your binding >"));
stackPanelFactory.AppendChild(title);
Run Code Online (Sandbox Code Playgroud)

为了显示以这种方式创建的StackPanel,您必须将它附加到VisualTree:

template.VisualTree = stackPanelFactory;
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你!:)


Pau*_*mek 9

我知道这是一个变通,但我发表在代码项目中的尖端(http://www.codeproject.com/Tips/808808/Create-Data-and-Control-Templates-using-Delegates),它允许你使用委托创建数据模板.例如:

TemplateGenerator.CreateDataTemplate(() => new TextBox());
Run Code Online (Sandbox Code Playgroud)

这足以创建一个创建新文本框的datatemplate.如果你也想要一个绑定,它可以写成:

TemplateGenerator.CreateDataTemplate
(
  () =>
  {
    var result = new TextBox();
    result.SetBinding(TextBox.TextProperty, "PathForTheBinding");
    return result;
  }
);
Run Code Online (Sandbox Code Playgroud)

TemplateGenerator的代码如下:

/// <summary>
/// Class that helps the creation of control and data templates by using delegates.
/// </summary>
public static class TemplateGenerator
{
  private sealed class _TemplateGeneratorControl:
    ContentControl
  {
    internal static readonly DependencyProperty FactoryProperty = DependencyProperty.Register("Factory", typeof(Func<object>), typeof(_TemplateGeneratorControl), new PropertyMetadata(null, _FactoryChanged));

    private static void _FactoryChanged(DependencyObject instance, DependencyPropertyChangedEventArgs args)
    {
      var control = (_TemplateGeneratorControl)instance;
      var factory = (Func<object>)args.NewValue;
      control.Content = factory();
    }
  }

  /// <summary>
  /// Creates a data-template that uses the given delegate to create new instances.
  /// </summary>
  public static DataTemplate CreateDataTemplate(Func<object> factory)
  {
    if (factory == null)
      throw new ArgumentNullException("factory");

    var frameworkElementFactory = new FrameworkElementFactory(typeof(_TemplateGeneratorControl));
    frameworkElementFactory.SetValue(_TemplateGeneratorControl.FactoryProperty, factory);

    var dataTemplate = new DataTemplate(typeof(DependencyObject));
    dataTemplate.VisualTree = frameworkElementFactory;
    return dataTemplate;
  }

  /// <summary>
  /// Creates a control-template that uses the given delegate to create new instances.
  /// </summary>
  public static ControlTemplate CreateControlTemplate(Type controlType, Func<object> factory)
  {
    if (controlType == null)
      throw new ArgumentNullException("controlType");

    if (factory == null)
      throw new ArgumentNullException("factory");

    var frameworkElementFactory = new FrameworkElementFactory(typeof(_TemplateGeneratorControl));
    frameworkElementFactory.SetValue(_TemplateGeneratorControl.FactoryProperty, factory);

    var controlTemplate = new ControlTemplate(controlType);
    controlTemplate.VisualTree = frameworkElementFactory;
    return controlTemplate;
  }
}
Run Code Online (Sandbox Code Playgroud)

它也有一个ControlTemplates的方法.