C# 加载并创建数据模板的实例

C# 加载并创建数据模板的实例,c#,wpf,datatemplate,C#,Wpf,Datatemplate,我有一个ItemsControl用于显示如下项目的视图: <ItemsControl ItemsSource="{Binding Items}"> <ItemsControl.ItemTemplate> <DataTemplate> <ContentControl Content="{Binding View}" /> </DataTemplate> </It

我有一个
ItemsControl
用于显示如下项目的
视图

<ItemsControl ItemsSource="{Binding Items}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <ContentControl Content="{Binding View}" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
伪码

Items.Add(new Item { Text = "1", View = LoadTemplate("type1") });
Items.Add(new Item { Text = "2", View = LoadTemplate("type2") });

object LoadTemplate(string key)
{
    var resource = FindResource(key);
    ... // what next?
}

不应在视图模型中创建UI控件,如
文本块
复选框
,而应创建CLR对象:

public class MyTextClass
{
    public string Text { get; set; }
}

...

var view = new MyTextClass();
var item = new Item { Text = "1", View = control };
然后,您可以在视图中使用
DataTemplate
,将CLR对象的实例与控件关联:

<DataTemplate DataType="local:MyTextClass">
    <TextBlock Text="{Binding Text}" />
</DataTemplate>


设置
DataTemplate
DataType
属性时,如果未指定
x:Key
DataTemplate
自动应用于该类型的数据对象:

而不是在视图模型中创建诸如
TextBlock
复选框之类的UI控件。您应该创建一个CLR对象:

public class MyTextClass
{
    public string Text { get; set; }
}

...

var view = new MyTextClass();
var item = new Item { Text = "1", View = control };
然后,您可以在视图中使用
DataTemplate
,将CLR对象的实例与控件关联:

<DataTemplate DataType="local:MyTextClass">
    <TextBlock Text="{Binding Text}" />
</DataTemplate>

当您设置
DataTemplate
DataType
属性而不指定
x:Key
时,
DataTemplate
将自动应用于该类型的数据对象:

如果您必须在视图模型中使用UIElements(而不是模板),同时希望在xaml中声明它们,然后

  • 不要使用数据模板
  • 在UIElement上使用
    x:Shared=“False”
如果您必须在视图模型中使用UIElements(而不是模板),同时希望在xaml中声明它们,那么

  • 不要使用数据模板
  • 在UIElement上使用
    x:Shared=“False”

我知道使用数据模板的标准方法,虽然它不适用于我的案例,但答案可能对未来的读者有用,谢谢。至于原因,
视图
将在附加到可视化树(例如,放入另一个容器)之前进行修改,数据模板的延迟性质使得很难(不可能?)实现。我知道使用数据模板的标准方法,虽然它不适用于我的情况,但答案可能对未来的读者有用,谢谢。由于种种原因,
视图
将在附加到可视化树(例如放入另一个容器)之前进行修改,并且数据模板的延迟特性使得很难(不可能?)实现。
<Window.Resources>
    <TextBlock x:Key="type1" x:Shared="False" Text="{Binding Text}"/>
    <CheckBox x:Key="type2" x:Shared="False" Content="{Binding Text}"/>
</Window.Resources>
object LoadTemplate(string key)
{
    return FindResource(key);
}