web-dev-qa-db-ja.com

コードビハインドでDataTemplateを作成する

プログラムでコントロールをデータテンプレートに追加するにはどうすればよいですか?

例えば。以下では、TextBlockとDataTemplateを作成しました。

TextBlock text = new TextBlock();
DataTemplate template = new DataTemplate();

次に、TextBlockをDataTemplateに追加する必要があります。これを達成する方法は?

コードビハインドでaddindデータテンプレートを使用する他の方法があることを知っています1. XAMLでデータテンプレートを作成し、コードビハインドでロードします2. XamlParserを使用して作成および追加します

しかし、私は例で示した方法で行う必要があります。

助けが要る。

23
MYRAO

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;
}

Msdnから取得した公式行: http://msdn.Microsoft.com/en-us/library/system.windows.frameworkelementfactory.aspx

こちらのFredrik Hedbladの投稿のコード例: XamlReaderがDataTemplateを生成する際の問題

34

最初にDataTemplateを宣言する必要があります。

DataTemplate template = new DataTemplate { DataType = typeof(< Type of the object the template refers>) };

次に、StackPanelのようなレイアウトパネルをこのように宣言します。

FrameworkElementFactory stackPanelFactory = new FrameworkElementFactory(typeof(StackPanel));
stackPanelFactory.SetValue(StackPanel.OrientationProperty, Orientation.Vertical);

そして最後に、TextBlockピースをそれにアタッチします。

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

この方法で作成されたStackPanelを表示するには、それをVisualTreeにアタッチする必要があります。

template.VisualTree = stackPanelFactory;

それが役に立てば幸い! :)

31
Archedius

私はそれが回避策であることを知っていますが、コードプロジェクトのヒントを公開しました( http://www.codeproject.com/Tips/808808/Create-Data-and-Control-Templates-using-Delegates )デリゲートを使用してデータテンプレートを作成できます。例えば:

TemplateGenerator.CreateDataTemplate(() => new TextBox());

これで、新しいテキストボックスを作成するデータテンプレートを作成できます。バインディングも必要な場合は、次のように記述できます。

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

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;
  }
}

また、ControlTemplatesのメソッドもあります。

9
Paulo Zemek