The Microsoft TabControl is a popular control to use as a region in a WPF Prism application. Unfortunately, the Microsoft TabControl comes with some limitations, such as the inability to close tab items. If you want to close tab items in the Microsoft TabControl, you need to implement this functionality yourself. However, you can make this easy on yourself by using the Infragistics xamTabControl. The xamTabControl extends the Microsoft TabControl and adds a number of features that you would normally have to write yourself otherwise. For example; closing tab items is built into the control. Another great thing is that nothing syntactically really changes when you use the xamTabControl as a Prism Region. So switching out the TabControl for the Infragistics xamTabControl is no big deal. Everything is the same.
Let’s take a look at a view that uses the xamTabControl as a region and adds support for closing tab items.
As you can see, this is a very simple view. It uses the xamTabControl as it’s region and it also has a couple of buttons on it that we will use to navigate to different views in the xamTabControl region. So when you run the application and click the buttons a couple of times, you will end up with something like this:
Okay, it’s nothing special right now. It looks just like it did if we were to use the Microsoft TabControl. Now let’s say we want to add support for closing tab items. Well, no problem! This is as easy as using a property. The TabItemCloseButtonVisibility property to be exact.
Run the application and now we get those cool little close buttons automatically.
Pretty cool right? Heck yeah it’s cool! Run the app and start opening and closing tabs until your heart’s content. But…… We actually have a major issue here. We are using Prism. We have this thing called a Region. This region holds all of the views we add to it until we remove them from the region. Unfortunately, when you click on that pretty little close button, the view seems to be removed from the control, but in actuality it is still hanging around in our Region. This is because the close button has no idea that we are using Prism, or that we need to remove the view we just closed form the Region.
So how do we fix this? Simple… we need a custom behavior. This one right here:
Now simply apply the Behavior to our xamTabControl by using System.Windows.Interactivity. Like so:
What this Behavior does is hooks into the TabItemEx.Closing and TabItemEx.Closed events so that we can execute our Prism logic during the tab item closing process. First, we need to respect whether we can even close the tab. This is done by checking the IConfirmNavigationRequest interface on the view we are trying to remove in the Closing event. If our View or ViewModel returns false during the ConfirmNavigationRequest method call, then the tab item cannot be closed. Otherwise, we will allow the tab item to be closed. For example; let’s say I had some rule that wouldn’t allow ViewB to be closed. I simply pass “false” in the continuationCallback within the ConfirmNavigationRequest method, and prompt the user letting them know why this tab couldn’t be closed.
This bring us to the TabItemEx.Closed event. Now that we know if we can or cannot close a tab, we simply get the view from the tab item, and then remove it from the region. But, before we remove it, we want to invoke the NavigatedFrom method on the INavigationAware interface so that we can respond to when a tab is closed from within our View or ViewModel to do any last minute clean up or state management.
That’s it! You have now added complete Prism Navigation support for closing tab items when using the xamTabControl as a Prism region. Hopefully you will find this useful, and maybe even use this in your WPF Prism applications. Be sure to check out the source code, and start playing with it. As always, feel free contact me on my blog, connect with me on Twitter (@brianlagunas), or leave a comment below for any questions or comments you may have.