2

質問

基本的には次のことをしたいのですが、できないようです。

UserControl myControl = new UserControl();
DataTemplate template = new DataTemplate(myControl);

質問:UserControlインスタンスからDataTemplateを構築することは可能ですか?そうでない場合、他に考えられる解決策はありますか?


本当の問題

私は、UIビューの大部分が単純な静的なWordのようなドキュメントであるプロジェクトに取り組んでいます(たとえば、いくつかのテキストフィールドやいくつかの画像、あまり派手ではありません)。このプロジェクトに取り組んでいる人のほとんどはコーダーではないため、UI生成用の非常にシンプルな社内マークアップ言語を設計しました。シンプルビューのマークアップの例は次のとおりです。

First name: [Person.FirstName]
Last name: [Person.LastName]
Address: [Person.Address.Street], [Person.Address.City]

これで、これらのテンプレートが実行時にロードされ、それらに基づいてユーザーコントロールが作成されます。この場合、1つのユーザーコントロールが作成され、スタックパネルとテキストブロックが2つだけ含​​まれるため、結果のコントロールはテキストドキュメントのように見えます。XAMLに相当するものは次のようになります。

<StackPanel>
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="First name: "/>
        <TextBlock Text={Binding Person.FirstName}
    </StackPanel>
    <StackPanel>
        ...
    </StackPanel>
    ...
</StackPanel>

それから、リストのサポートを実装し始めましたが、それを行う方法を考えることができませんでした。理論的には単純で、次の構文(+ XAMLに相当)を思いつきました。

[List Customers]
First name: [Person.FirstName]
Last name: [Person.LastName]
Address: [Person.Address.Street], [Person.Address.City]
[EndList]

->

<StackPanel>
    <ItemsControl ItemsSource="{Binding Customers}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                [Insert code from previous XAML example here]
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</StackPanel>

しかし、UserControlインスタンスから直接DataTemplateを構築できないように思われるため、これを行うことはできません。私のUserControlsがタイプであれば問題はありませんが、そうではありません。

考えられる解決策の1つは、ItemsControl.ItemsをUserControlsのリストに直接バインドすることです(ItemsSourceItemTemplateにバインドする代わりに)が、いくつかの理由から、これはこの場合は最適ではありません。私は最初に他のいくつかの解決策を試してみることをいとわないでしょう!

アップデート

明確にするために:私が持っているのは、必要なコンテンツを含むUserControlクラスのプレーンインスタンスだけです。例えば

UserControl control = new UserControl();
var panel = new StackPanel();
panel.Children.Add(...);
panel.Children.Add(...);
control.Content = panel;
// How to use that control as ItemTemplate for ItemsControl?
// It seems that it is not possible directly but I want to
// know what my options are.

実行時に作成しているため、クラスがありません。また、非常に面倒なので、ILコードを発行して新しい型を動的に作成したくありません。

4

3 に答える 3

6

コード ビハインドからデータ テンプレートを作成すると、次のようになります。

FrameworkElementFactory factory = new FrameworkElementFactory(MyUserControl.GetType());
DataTemplate dt = new DataTemplate();
dt.VisualTree = factory;

yourItemsControlInstance.ItemTemplate = dt;

データ テンプレートは、実行時に構築されるコントロールの定義です。これは、ElementFactory を使用したこの構築方法です。ItemsControl 内のすべての項目に対して UserControl の同じインスタンスは必要ありません。

于 2012-11-29T13:22:13.450 に答える
1

ああ、私は今あなたの問題を理解しています。UserControl インスタンスからデータ テンプレートを作成する簡単な方法 (1 ~ 2 行のコード) はないと思います。

しかし、あなたの問題を解決するために、私は2つの方向を見ています:

  1. ユーザー コントロールが作成された時点で、代わりにデータ テンプレートを作成し、それを使用します。ネストされた FrameworkElementFactories では面倒です。私はそれをしたことがなく、MSDN のドキュメントによると、Xaml のデータ テンプレートと比較して実行できないいくつかの制限が発生する可能性があります。しかし、それが単純であれば、実行可能でなければなりません。以前は、(必要に応じて) ガイダンスとして使用できる Sacha Barber による codeproject 記事がありました。
  2. と呼ばれるメソッドに UserControl の作成をパックします。private UserControl createMyUserControl(){}

そして、次のようにします。

    ItemsControl itemsControl = new ItemsControl();
    foreach (var customer in Customers) 
    {
       var usercontrol = createMyUserControl(...);
       usercontrol.DataContext = customer;
       itemsControl.Items.Add(usercontrol);
    }

私の意見では、2 番目のオプションはあまり洗練されていないため、最初にオプション 1 を確認します。

WPF: コード/および魔法のコンテンツでスタイルを作成する方法 (コード ビハインドの DataTemplate の広範なサンプルについては、最後のセクションを参照してください)

于 2012-11-30T07:34:15.860 に答える
0

UserControlで代用できると思いますContentControl。のコンテンツをContentControl目的のテンプレートに設定し、ItemsControl の ItemTemplate として使用するだけです。

于 2012-11-30T10:35:59.237 に答える