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.
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:
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.
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):
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).
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...).
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