05 October 2011

XAML - Makes the tab headers justify on the width of the whole tab control

Take a TabControl with a row of headers on top.
How do you make those headers justify so that together they have (more or less) the same width as the control?
Like this:

The converter

You need a converter to calculate the width a TabItem should have:
public class TabJustifyConverter : IValueConverter {
  public object Convert(object value,
                        Type targetType,
                        object parameter,
                        CultureInfo culture) {
    if (value == null) {
      return 0;
    }
    else if (!(value is TabControl)) {
      throw new Exception(@"The TabJustifyConverter must
                            be supplied a TabControl.");
    }
    else {
      TabControl tab = value as TabControl;
      int count = 0;
      foreach (TabItem item in tab.Items)
        if (item.Visibility == Visibility.Visible)
          count++;
      return (tab.ActualWidth / count) - 2;
    }
  }

  public object ConvertBack(object value,
                            Type targetType,
                            object parameter,
                            CultureInfo culture) {
    throw new NotImplementedException();
  }
}

The XAML

In XAML, give the TabControl a name.
Then bind each TabItem's width to this control and use the converter:
<controls:TabItem x:Name="tabCustomer"
          Header="Customer"
          Width="{Binding ElementName=tabControl,
                          Converter={StaticResource TabJustifyConverter}}">
I tried putting that in a resource, but kept getting a "cannot set read-only property"-exception.

No comments:

Post a Comment