我有ItemsControl
用于显示View
这样的项目:
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding View}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
以下简短介绍给您一个想法:
public class Item
{
public string Text { get; set; }
public object View { get; set; }
... // more properties used in bindings
}
public partial class MainWindow : Window
{
public ObservableCollection<Item> Items { get; } = new ObservableCollection<Item>();
public MainWindow()
{
InitializeComponent();
// 1
{
var control = new TextBlock();
var item = new Item { Text = "1", View = control };
BindingOperations.SetBinding(control, TextBlock.TextProperty, new Binding(nameof(Item.Text)) { Source = item });
Items.Add(item);
}
// 2
{
var control = new CheckBox();
var item = new Item { Text = "2", View = control };
BindingOperations.SetBinding(control, CheckBox.ContentProperty, new Binding(nameof(Item.Text)) { Source = item });
Items.Add(item);
}
// ... and so on
DataContext = this;
}
}
正如您所看到的,每个项目都已预先创建View
(不幸的是,这不能改变),可以是任何内容,包括绑定等。
我的问题:如何将View
创建为xaml(作为数据模板)?
Pseudoxaml:
<SomeContainer.Resources>
<DataTemplate x:Key="type1">
<TextBlock Text="{Binding Text}" />
</DataTemplate>
<DataTemplate x:Key="type2">
<CheckBox Content="{Binding Text}" />
</DataTemplate>
</SomeContainer.Resources>
<ItemsControl ... /> <!-- same definition as early? -->
伪代码
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?
}
答案 0 :(得分:1)
您应该创建一个CLR对象,而不是在视图模型中创建诸如TextBlock
或CheckBox
之类的UI控件:
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>
当您设置DataType
的{{1}}属性而未指定DataTemplate
时,x:Key
会自动应用于该类型的数据对象:https://msdn.microsoft.com/en-us/library/system.windows.datatemplate.datatype(v=vs.110).aspx
答案 1 :(得分:1)
如果绝对必须在视图模型中使用UIElements(而不是模板),并且同时想要在xaml中声明它们,那么
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>
每次申请资源时,您都会获得一份新副本
LoadTemplate方法简化为FindResource
object LoadTemplate(string key)
{
return FindResource(key);
}