WPF:哪种解决方案?带有关闭按钮和新选项卡按钮的选项卡控件
本文关键字:选项 控件 按钮 新选项 解决方案 关闭按钮 WPF | 更新日期: 2023-09-27 18:20:53
我正在尝试为TabControl找到最佳解决方案,该解决方案既支持每个TabItem上的关闭按钮,又始终显示"新选项卡按钮"作为最后一个选项卡。
我已经找到了一些半工作的解决方案,但我认为这是针对 MVVM 的,我没有使用。足以尝试理解WPF =(
这是我迄今为止找到的最佳解决方案:http://www.codeproject.com/Articles/493538/Add-Remove-Tabs-Dynamically-in-WPF
我真正理解的解决方案。但问题是它正在使用 ItemsSource,我不希望这样。我想将 ItemsSource 绑定到我自己的集合,而不必在该集合中具有特殊的东西来处理新的选项卡按钮。
我已经搜索了好几天,但找不到好的解决方案。而且我对 WPF 真的很陌生,否则我可能会改编我找到的半成品解决方案,或者使它们完整。但不幸的是,这目前远远超出了我的范围。
任何帮助表示赞赏。
我有一个开源库,它支持 MVVM 并允许将额外的内容(例如将按钮添加到选项卡条中(。它是运动铬风格的标签,可以撕掉。
http://dragablz.net
这是一种无需太多工作即可实现放置在最后一个 TabItem 旁边的添加 (+( 按钮的肮脏方法。您已经知道如何在 TabItem 标题旁边放置"删除"按钮,因此我未在此处包含该逻辑。
基本上这个解决方案中的逻辑是
- 将 ItemsSource 属性绑定到您自己的集合以及 使用复合集合添加选项卡项。
- 禁用选择添加(+( 选项卡项,而是执行操作以在它时加载新选项卡被单击/选中。
XAML 位
<TextBlock x:Name="HiddenItemWithDataContext" Visibility="Collapsed" />
<TabControl x:Name="Tab1" SelectionChanged="Tab1_SelectionChanged" >
<TabControl.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding DataContext.MyList, Source={x:Reference HiddenItemWithDataContext}}" />
<TabItem Height="0" Width="0" />
<TabItem Header="+" x:Name="AddTabButton"/>
</CompositeCollection>
</TabControl.ItemsSource>
</TabControl>
背后的代码
private void Tab1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Contains(AddTabButton))
{
//Logic for adding a new item to the bound collection goes here.
string newItem = "Item " + (MyList.Count + 1);
MyList.Add(newItem);
e.Handled = true;
Dispatcher.BeginInvoke(new Action(() => Tab1.SelectedItem = newItem));
}
}
您可以制作一个附加"添加"选项卡的转换器。这样,视图模型中的选项卡集合将仅包含真正的选项卡。
那么问题是如何知道何时选择了"添加"选项卡。您可以创建一个 TabItem 行为,该行为在选择选项卡时执行命令。顺便说一下,我最近为另一个问题推荐了这个,所以你可以从那里获取代码:TabItem 选定行为
虽然我实际上没有编码的解决方案,但我可以深入了解在 WPF/MVVM 模式中处理此问题的适当方法。
首先,如果我们分解请求,如下所示:
- 您有一系列要显示的元素。
- 您希望用户能够从序列中删除单个元素。
- 您希望用户能够向序列添加新元素。
此外,由于您尝试使用 TabControl
,因此还希望获取 Selector
控件提供的行为(元素选择(,以及用于显示所选元素(内容(的区域。
因此,如果我们坚持这些行为,您将没事,因为用户界面控件可以根据外观和感觉进行自定义。
当然,最好的控制是 TabControl
,您已经在尝试使用。如果我们使用此控件,则它满足第一项。
<TabControl ItemsSource="{Binding Path=Customers}" />
之后,您可以自定义每个元素,在您的情况下,您希望为每个元素添加一个Button
,这将执行命令以从序列中删除该元素。这将满足第二项。
<TabControl ...>
<TabControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=CustomerId}" />
<Button Command="{Binding Path=RemoveItemCommand, Mode=OneTime,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type TabControl}}"
CommandParameter="{Binding}" />
</StackPanel>
</DataTemplate>
<TabControl.ItemTemplate>
</TabControl>
最后一部分有点困难,需要您实际必须创建一个继承自 TabControl
类的自定义控件,添加一个ICommand
DependencyProperty
,并自定义控件模板,以便它不仅显示TabPanel
,而且在它旁边还显示一个处理您刚刚创建的DependencyProperty
的Button
(按钮的外观和感觉必须也可以定制(。执行所有这些操作将允许您显示自己的TabControl
版本,该版本具有 假TabItem
,这当然是您的"添加"按钮。这说起来容易做起来难,祝你好运。请记住,TabPanel
换行多行,可以水平或垂直。基本上,最后一部分一点也不容易。