【发布时间】:2020-01-26 22:47:57
【问题描述】:
我有一个绑定到其 viewmodel Items 属性的 TabControl:
<TabControl ItemsSource="{Binding Items}"/>
这是视图模型类:
public class ViewModel
{
public ObservableCollection<object> Items { get; } = new ObservableCollection<object>();
public ViewModel()
{
Items.Add(new Person() { FirstName = "Alan", LastName = "Turing" });
Items.Add(new Car() { ModelName = "Fiesta", Manifacturer = "Ford" });
}
}
Items的类型是ObservableCollection<object>;这是因为每个选项卡都代表一种不同的对象,在这个例子中是一个人和一辆汽车。
问题
我想将选项卡的标题绑定到不能作为绑定类的属性使用的文本,比如说手动提供的标题。
例如,我希望第一个选项卡将文本“Person”作为标题,第二个将文本“Car”作为标题:
我想到了:
- 将 Header 属性添加到每个类。从绑定的角度来看,它简单明了,但这是一种通用查看器,并非所有输入数据的接口都可以修改。
- “附加属性”仍需要在类级别上执行;但可行,但可能有点矫枉过正
-
在视图模型级别定义的
Dictionary<object, string>,我们称之为标题。
每次我向集合中添加一个对象时,我也会在 Headers 字典中添加一个 Header。它的关键是对象本身。Person p = new Person() { FirstName = "Alan", LastName = "Turing" }; Headers.Add(p, "Person"); Items.Add(p);
那么绑定表达式怎么写呢?
<TabControl ItemsSource="{Binding Items}">
<TabControl.ItemTemplate>
<DataTemplate>
<Label Content="{Binding ????????}"/>
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
即使可能,这个解决方案似乎也不是很“绑定友好”。
这里似乎有两个问题:动态地将信息附加到实例,并通过绑定访问它。
有什么想法吗?
后记 - 代码
代码,为了完整性。 我的课:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Car
{
public string ModelName { get; set; }
public string Manifacturer { get; set; }
}
我的数据模板,在<Winodow.Resources> 标签中定义。
<DataTemplate DataType="{x:Type local:Person}">
<StackPanel>
<Label Content="{Binding FirstName}"/>
<Label Content="{Binding LastName}"/>
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type local:Car}">
<StackPanel>
<Label Content="{Binding Manifacturer}"/>
<Label Content="{Binding ModelName}"/>
</StackPanel>
</DataTemplate>
【问题讨论】:
-
我肯定会使用 IValueConverter 将对象转换为正确的标题。
-
替代方案也可以是
HeaderTemplateSelector。然后你可以根据类型来决定。 -
一个名为 Items 的 Dictionary
怎么样?然后在标题中绑定到键,在选项卡中您可以使用绑定到值的内容演示器。
标签: c# wpf data-binding