带有添加新选项卡按钮 (+) 的 TabControl
在 WPF 中选项卡控件的选项卡条中的所有选项卡项的末尾添加“+”按钮选项卡的正确方法是什么?
- 它应该可以正确地处理多个选项卡标题行。
- 它应该位于所有选项卡项的末尾
- 选项卡循环应该正常工作(Alt + Tab),即
+
选项卡应该是跳过了。 - 我不必修改我绑定到的源集合。也就是说,控件应该是可重用的。
- 该解决方案应适用于 MVVM
更准确地说,该按钮应该完全显示为附加的最后一个选项卡,而不是所有选项卡条行右侧某处的单独按钮。
我只是在寻找执行此操作的一般方法。
谷歌抛出了很多例子,但如果你深入挖掘的话,没有一个能够满足以上五点。
What is the proper way of adding a '+' button tab at the end of all the tab items in the tab strip of a tab control in WPF?
- It should work correctly with multiple tab header rows.
- It should be at the end of all tab items
- Tab cycling should work correctly (Alt + Tab), that is, the
+
tab should be skipped. - I shouldn't have to modify the source collection I am binding to. That is, the control should be reusable.
- The solution should work with MVVM
To be more precise, the button should appear exactly as an additional last tab and not as a separate button somewhere on the right of all tab strip rows.
I am just looking for the general approach to doing this.
Google throws many examples, but if you dig a little deep none of them satisfy all the above five points.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
我使用了选项卡控件模板的修改并绑定到视图模型中的 AddNewItemCommand 命令。
XAML:
相关视图模型中的代码如下所示:
注意:我通过 StackPanel 将 TabPanel 包装为根据属性“TabStripPlacement”的值,将“+”按钮与 TabPanel 一起翻转。在您看来,没有继承,也没有代码隐藏。
I used a modification of the tab control template and binding to the AddNewItemCommand command in my view model.
XAML:
Code in the relevant view model looks like this:
Pay attention: I wrapped TabPanel by StackPanel to flip the "+" button together with TabPanel regarding to value of property "TabStripPlacement". Without inheritance and without code-behind in your view.
我相信我已经想出了一个完整的解决方案,我开始使用 NVM 的解决方案来创建我的模板。然后参考DataGrid源代码,提出了一个能够添加和删除项目的扩展TabControl。
ExtendedTabControl.cs
CustomStyleSelector.cs
TemplateSelector.cs
Generic.xaml
I believe I have come up with a complete solution, I started with NVM's solution to create my template. And then referenced the DataGrid source code to come up with an extended TabControl capable of adding and removing items.
ExtendedTabControl.cs
CustomStyleSelector.cs
TemplateSelector.cs
Generic.xaml
像这样定义 TabControl 的 ControlTemplate:
网格中的上面一行将是 TabPanel,但您可以将其放入 StackPanel 中,并在 TabPanel 后面放置一个按钮,并将按钮设置为看起来像选项卡。
现在,该按钮将创建一个新的 TabItem(可能是您自定义创建的),并将其添加到作为 TabControl 的 Itemssource 的 ObservableCollection of Tabs 中。
2& 3) 它应该始终出现在末尾,并且它不是选项卡,因此希望不是选项卡循环的一部分
4) 那么,您的 TabControl 应该使用 TabItems 的 ObservableCollection 作为 Itemssource,以便在添加/删除新项目时收到通知
一些代码:
NewTabButton 用户控件 .cs 文件
和主窗口:
现在我们需要找到一种方法,让它始终显示在右下角,并为其添加事件和样式(加号作为占位符)。
Define the ControlTemplate of the TabControl like this:
The upper row in the grid would be the TabPanel, but you would put that into a StackPanel with a button following the TabPanel, and style the button to look like a tab.
Now the button would create a new TabItem (your custom-created one perhaps) and add it to the ObservableCollection of Tabs you have as the Itemssource for your TabControl.
2 & 3) It should always appear at the end, and it's not a tab so hopefully not part of tab cycling
4) Well, your TabControl should use a ObservableCollection of TabItems as Itemssource to be notified when a new one is added/removed
Some code:
The NewTabButton usercontrol .cs file
And the main window:
Now we would need to find a way to let it always appear bottom right and also add the event and style for it (the plus sign is there as a placeholder).
作为对 @NVM 自己的解决方案的评论,这可能会更好;但我还没有代表发表评论,所以...
如果您尝试使用接受的解决方案并且没有触发添加命令,那么您可能没有名为“parentUserControl”的用户控件。
您可以按如下方式更改 @NVM 的 TabControl 声明以使其正常工作:
显然,这不是一个给选项卡控件起好名字:);但我猜@NVM 将数据上下文进一步连接到他的视觉树上的一个元素以匹配名称。
请注意,我个人更喜欢通过更改以下内容来使用相对绑定:
对此:
This would likely be better as a comment on @NVM's own solution; but I don't have the rep to comment yet so...
If you are trying to use the accepted solution and not getting the add command to trigger then you probably don't have a usercontrol named "parentUserControl".
You can alter @NVM's TabControl declaration as follows to make it work:
Obviously not a good name to give a tab control :); but I guess @NVM had the data context hooked further up his visual tree to an element to match the name.
Note that personally I preferred to use a relative binding by changing the following:
To this:
除了NVM的回答。
我没有为 NewItemPlaceholder 使用这么多模板和选择器。更简单的解决方案,没有空内容:
Ctrl+Tab 我决定禁用。这并不容易,您应该在父元素(即 Window)上订阅 KeyDown (Ctrl+Shift+Tab 也可以正确处理):
In addition to NVM's answer.
I don't use so many templates and selector's for NewItemPlaceholder. Easier solution with no empty content:
Ctrl+Tab I desided to disable. It's not SO easy, you should subscribe on KeyDown on parent element, i.e. Window (Ctrl+Shift+Tab also handled correctly):
要完成 @NVM 给出的答案,您必须添加 PreviewMouseDown 事件:
然后:
To complete the answer given by @NVM what you have to add is the PreviewMouseDown event:
And then:
使用 IEditableCollectionView 的几乎完整的解决方案:
它几乎完整,因为选项卡循环不会跳过“+”选项卡,并且会显示空内容(这不太好,但我可以忍受它,直到出现更好的解决方案。 ..)。
An almost complete solution using IEditableCollectionView:
It's almost complete, because the tab cycle doesn't skip the '+' tab, and will show empty content (which is not exactly great, but I can live with it until a better solution come around...).
现有的答案对我来说太复杂了,而且我很懒。所以,我尝试实现一个非常简单的想法。
这个想法很简单,但是该死的 WPF 太冗长了,所以代码变得有点长。但这可能很容易理解......因为即使是我也是如此。
代码隐藏。
XAML
Existing answers were too complex for me and I am lazy. So, I tried to implement a very simple idea.
The idea was simple, but the damn WPF is verbose, so the code became a little bit long. But it probably is very simple to understand... because even I did.
Code behind.
XAML