如何从 UserControl 实例创建 DataTemplate?

use*_*511 2 c# wpf user-controls datatemplate

基本上我想做以下事情,但似乎我不能:

UserControl myControl = new UserControl();
DataTemplate template = new DataTemplate(myControl);
Run Code Online (Sandbox Code Playgroud)

问题:是否可以从 UserControl 实例构造 DataTemplate?如果没有,还有其他可能的解决方案吗?


真正的问题

我正在做一个项目,其中大部分 UI 视图都是简单的静态 Word 类文档(例如,一些文本字段和一些图像,没什么特别的)。因为在这个项目上工作的大多数人都不是编码员,所以我们为 UI 生成设计了非常简单的内部标记语言。简单视图的标记示例如下:

First name: [Person.FirstName]
Last name: [Person.LastName]
Address: [Person.Address.Street], [Person.Address.City]
Run Code Online (Sandbox Code Playgroud)

现在这些模板在运行时加载,用户控件是基于它们创建的。在这种情况下,将创建一个用户控件,它只包含几个堆栈面板和文本块,因此生成的控件看起来有点像文本文档。XAML 等效项类似于:

<StackPanel>
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="First name: "/>
        <TextBlock Text={Binding Person.FirstName}
    </StackPanel>
    <StackPanel>
        ...
    </StackPanel>
    ...
</StackPanel>
Run Code Online (Sandbox Code Playgroud)

然后,我开始实现对列表的支持,但想不出如何做到这一点。理论上它很简单,我想出了以下语法(+ 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>
Run Code Online (Sandbox Code Playgroud)

但我不能这样做,因为我似乎无法直接从 UserControl实例构造 DataTemplate 。如果我的 UserControls 是types不会有问题,但它们不是。

一种可能的解决方案是,我可以将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.
Run Code Online (Sandbox Code Playgroud)

我没有它的类,因为我是在运行时构造它,而且我不想通过发出 IL 代码来动态创建新类型,因为它太痛苦了。

Gra*_*fix 5

从背后的代码创建数据模板是这样的:

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

yourItemsControlInstance.ItemTemplate = dt;
Run Code Online (Sandbox Code Playgroud)

数据模板是要在运行时构建的控件的定义,这就是使用 ElementFactory 构建的方式。您不希望 ItemsControl 中的每个项目都具有相同的 UserControl 实例。