如何解决带有两个数据绑定的 TabControl
我有一个 TabControl
,我想拥有 2 个数据绑定。一个是为列表中的每个项目设置一个 TabItem
,另一个是一个 Summary 并使用一个 TabItem
来显示控件模板另一个列表中的每个项目。
我可以将 ItemsControl
设置为这两种类型的数据绑定之一,但不能同时设置这两种类型的数据绑定。我怎样才能让 TabControl 做到这两点?
我可以以某种方式在 TabControl
中添加一个额外的 TabItem
到 TabControl
,ItemSource
集吗?然后我可以使用 XAML 加载新的额外 Binding
。
解决方法
公开组合集合
您可以在您的视图模型中公开一个集合,该集合将集合和附加项组合在一起,如下所示(如果您不修改该集合,您也可以使用任何其他可枚举类型)。
public class MyViewModel : INotifyPropertyChanged
{
public MyViewModel()
{
var myTabItemCollection = // ...get the items collection.
var mySummaryTabItem = // ...get the summary item.
TabItems = new ObservableCollection<string>(myTabItemCollection)
{
mySummaryTabItem
};
}
public ObservableCollection<MyTabItemViewModel> TabItems { get; }
// ...other properties,methods,...
}
使用复合集合
有一种专用的 CompositeCollection
类型用于在 XAML 中组合一个或多个集合和单个项目。但是,这种类型具有 severe shortcommings in terms of data-binding。它既不是派生自 FrameworkElement
,也不是 Freezable
,这使得使用起来非常困难、繁琐且容易出错。为完整起见,我将介绍这种类型的解决方案。让我们假设这个视图模型:
public class MyViewModel : INotifyPropertyChanged
{
public ObservableCollection<MyTabItemViewModel> TabItems { get; }
public MyTabItemViewModel Summary { get; }
// ...other properties,...
}
理论上,如果 CompositeCollection
可以进行数据绑定(这不起作用),这将很容易:
<TabControl>
<TabControl.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding TabItems}" />
<TabItem DataContext="{Binding Summary}"
Header="{Binding}"
Content="{Binding}" />
</CompositeCollection>
</TabControl.ItemsSource>
</TabControl>
为了使其发挥作用,您可以应用各种方法,例如在这些相关问题中:
- How do you bind a CollectionContainer to a collection in a view model?
- CompositeCollection + CollectionContainer: Bind CollectionContainer.Collection to property of ViewModel that is used as DataTemplates DataType
- Binding to a single element inside a CompositeCollection
例如,我将使用 binding proxy 类型来启用 CompositeCollection
内的绑定。它将绑定到 DataContext
的 TabControl
并使用 Data
属性公开它。由于代理是一种资源,CompositeCollection
可以将其称为与 StaticResource
绑定的源。
<TabControl x:Name="TabControl">
<TabControl.Resources>
<local:BindingProxy x:Key="TabControlBindingProxy" Data="{Binding}" />
</TabControl.Resources>
<TabControl.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding Data.TabItems,Source={StaticResource TabControlBindingProxy}}" />
<TabItem DataContext="{Binding Data.Summary,Source={StaticResource TabControlBindingProxy}}"
Header="{Binding}"
Content="{Binding}" />
</CompositeCollection>
</TabControl.ItemsSource>
</TabControl>
这也适用于多个集合和单个项目,但请注意,此方法和相关问题中的其他方法 - 尽管它们编译和运行得很好 - 可能会使 Visual Studio 设计器崩溃,这是不幸的。因此,我建议您采用公开组合集合的方式,这种方式更可靠、更容易理解、更简单。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。