Show SelectedIndex in WPF Tabcontrol Header Template

I have 1 ... n tabcontrols in my application with the following XAML setup:

<TabControl Name="ordersTabControl" ItemsSource="{Binding CoilItems}">
  <TabControl.ItemTemplate>
    <DataTemplate DataType="models:Coil">
      <StackPanel>
        <TextBlock Text="{Binding CoilCode, StringFormat='Coil: {0}'}" />
        <TextBlock Text="{Binding ArticleCode, StringFormat='Auftrag: {0}'}" />
        <TextBlock Text="{Binding RestWeight, StringFormat='Restgewicht: {0} kg'}" />
      </StackPanel>
    </DataTemplate>
  </TabControl.ItemTemplate>
  <TabControl.ContentTemplate>
  [...]
  </TabControl.ContentTemplate>
</TabControl>

The number of open tabs changes at runtime. Now I want to show the index on each tab (i.e., the first tab shows "Order 1", the second "Order 2", etc.) In addition to the information already in each heading.

AFAIK when using a DataTemplate I can’t access the properties of a tab using code, so is there a way in XAML to link a text block inside a tabulator to show the index of this particular tab in tabcontrol?

I think this should be possible with RelativeSource and FindAncestors? Alas, I could not find a clear guide to these settings (and I just started using WPF 2 days ago).

+5
3

, . :

public static class IndexAttachedProperty
{


    #region TabItemIndex

    public static int GetTabItemIndex(DependencyObject obj)
    {
        return (int) obj.GetValue(TabItemIndexProperty);
    }

    public static void SetTabItemIndex(DependencyObject obj, int value)
    {
        obj.SetValue(TabItemIndexProperty, value);
    }

    // Using a DependencyProperty as the backing store for TabItemIndex.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TabItemIndexProperty =
        DependencyProperty.RegisterAttached("TabItemIndex", typeof (int), typeof (IndexAttachedProperty),
                                            new PropertyMetadata(-1));



    #endregion

    #region TrackTabItemIndex

    public static bool GetTrackTabItemIndex(DependencyObject obj)
    {
        return (bool) obj.GetValue(TrackTabItemIndexProperty);
    }

    public static void SetTrackTabItemIndex(DependencyObject obj, bool value)
    {
        obj.SetValue(TrackTabItemIndexProperty, value);
    }

    // Using a DependencyProperty as the backing store for TrackTabItemIndex.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TrackTabItemIndexProperty =
        DependencyProperty.RegisterAttached("TrackTabItemIndex", typeof (bool), typeof (IndexAttachedProperty),
                                            new PropertyMetadata(false, TrackTabItemIndexOnPropertyChanged));

    private static void TrackTabItemIndexOnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var tabControl = GetParent(d, p => p is TabControl) as TabControl;
        var tabItem = GetParent(d, p => p is TabItem) as TabItem;
        if (tabControl == null || tabItem == null)
            return;
        if (!(bool)e.NewValue)
            return;
        int index = tabControl.Items.IndexOf(tabItem.DataContext == null ? tabItem : tabItem.DataContext);
        SetTabItemIndex(d, index);
    }
    #endregion





    public static DependencyObject GetParent(DependencyObject item, Func<DependencyObject, bool> condition)
    {
        if (item == null)
            return null;
        return condition(item) ? item : GetParent(VisualTreeHelper.GetParent(item), condition);
    }
}

, , , , . - .

XAML :

        <TabControl.ItemTemplate>
            <DataTemplate DataType="{x:Type WpfApplication3:A}">
                <StackPanel x:Name="tabItemRoot" WpfApplication3:IndexAttachedProperty.TrackTabItemIndex ="True">
                    <TextBlock Text="{Binding Text}"/>
                    <TextBlock Text="{Binding Path=(WpfApplication3:IndexAttachedProperty.TabItemIndex), ElementName=tabItemRoot}"/>

                </StackPanel>
            </DataTemplate>
        </TabControl.ItemTemplate>

. .

:

enter image description here

, ...

+2

AlternationCount , .

bind AlternationCount

<TabControl AlternationCount="{Binding Path=Items.Count, RelativeSource={RelativeSource Self}}">

ItemTemplate TextBlock , AlternationIndex, ,

<TextBlock Text="{Binding Path=(ItemsControl.AlternationIndex), RelativeSource={RelativeSource  FindAncestor, AncestorType=TabItem}}" />

, , , .

+2

TabItem , , TabControl. ItemsControls , , - , ?

IndexOf, ItemsCollection . MultiValueConverter, DataTemplate.

:

   public class ItemsControlIndexConverter : IMultiValueConverter
   {
      public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
      {
         ItemCollection itemCollection = (ItemCollection)values[0];
         return (itemCollection.IndexOf(values[1]) + 1).ToString();
      }

      public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
      {
         throw new NotImplementedException();
      }
   }

TabControl XAML:

<TabControl ItemsSource="{Binding CoilItems}">
    <TabControl.Resources>
        <local:ItemsControlIndexConverter x:Key="IndexConverter"/>
    </TabControl.Resources>
    <TabControl.ItemTemplate>
         <DataTemplate>
             <StackPanel Orientation="Horizontal">
                 <TextBlock>
                     <TextBlock.Text>
                         <MultiBinding Converter="{StaticResource IndexConverter}" StringFormat="Order {0}" Mode="OneWay">
                             <Binding RelativeSource="{RelativeSource AncestorType=TabControl}" Path="Items"/> <!-- First converter index is the ItemsCollection -->
                             <Binding /> <!-- Second index is the content of this tab -->
                         </MultiBinding>
                     </TextBlock.Text>
                 </TextBlock>
                 <!-- Fill in the rest of the header template -->
             </StackPanel>
         </DataTemplate>
     </TabControl.ItemTemplate>
 </TabControl>
+1

All Articles