Search code examples
c#wpftabcontrolribbon

How do I programatically change tab names in a WPF TabControl?


All,

I have searched extensively for the solution here but I have a feeling my problem stems from a basic lack of knowledge about WPF. I am new to it and have thus far hacked and Googled my way through as best I can.

Basically, I have a Ribbon dynamically interacting with a TabControl. The Ribbon tabs select a category of items, the MenuItems in the RibbonGroups then choose an item within the category. Upon clicking an item, the tabs on the TabControl need to dynamically change. Whether that is just the Headers, the tabs themselves, or the entire TabControl is fine with me. Thus far, upon clicking a MenuItem on the inside one of the RibbonGroups, I attempt to just set the Header text equal to "blah" for each tab on the TabControl. Then the Header object throws a null pointer. This is what happens whether I set the Header, the Tabs, or the TabControl itself.

Why?!?!?!?

...and how in the world do I fix it???

Thanks!


Solution

  • WPF is designed with data/UI separation in mind. One of the reasons you're having trouble finding a solution is because what you're trying to do is a no-no; instead of programmatically changing the UI's header text, you should be changing the underlying data instead, and allowing the WPF plumbing to update how the data is displayed.

    A WPF tab control can literally contain any type of object; you could fill it with integers or strings or FooBars or whatever. There's no guarantee that any of these objects will define a Header property, and it's up to the developer to configure data bindings or templates which instruct the TabControl just how a FooBar or a whatever should be displayed.

    In an ideal WPF application which adheres to the MVVM design pattern, you might have your TabControl bound to a collection of view models which each define a HeaderText property. Your view models would implement the INotifyPropertyChanged interface so that when the HeaderText property was changed on the view model then the UI would get updated.

    Having said all that, if you've got an existing application it may be unrealistic to rewrite it from scratch using a different design pattern, and MVVM is not easily added on to an existing code base. If you're working with simple Designer generated UI without using any data binding, then the following code does what you ask. Sometimes.

    foreach(TabItem item in tabControl.Items)
        item.Header = "blah";
    

    ... but as I said before, there's no guarantee that a WPF TabControl's Items collection will contain items of type TabItem, so this code is not safe.