Jak rozciągnąć nagłówki elementów karty WPF do szerokości sterowania nadrzędnego

Czy w XAML istnieje sposób, aby nagłówki elementów karty rozciągały się na szerokość kontrolki tab?

Na przykład mam trzy zakładki: czerwoną, niebieską i zieloną. Jeśli mam kontrolkę tabulacji z jej szerokością ustawioną na auto, nagłówki tabulatorów wypełnią tylko część przestrzeni nad zawartością kart, ale chcę, aby wypełniły całą przestrzeń. Dla mojego przykładu z trzema zakładkami, czerwony powinien zająć pierwszą trzecią kontrolki, niebieski powinien zająć trzecią środkową, a zielony ostatnią trzecią.

I mam pomysł, jak to zrobić w kodzie, za którym pracuję teraz, ale jestem zainteresowany zrobieniem tego w najprostszy możliwy sposób.

Author: Nathan Van Dyken, 2009-04-01

11 answers

Wziąłem przykład Jordana i wprowadziłem w nim pewne zmiany. Ta wersja powinna działać dla dowolnej liczby zakładek:

namespace WpfApplication1.Converters
{
    public class TabSizeConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
            TabControl tabControl = values[0] as TabControl;
            double width = tabControl.ActualWidth / tabControl.Items.Count;
            //Subtract 1, otherwise we could overflow to two rows.
            return (width <= 1) ? 0 : (width - 1);
        }

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

Ta sama przestrzeń nazw w xaml:

xmlns:local="clr-namespace:WpfApplication1.Converters"

I to sprawi, że wszystkie zakładki z niego skorzystają:

<Window.Resources>
    <local:TabSizeConverter x:Key="tabSizeConverter" />
    <Style TargetType="{x:Type TabItem}">
        <Setter Property="Width">
            <Setter.Value>
                <MultiBinding Converter="{StaticResource tabSizeConverter}">
                    <Binding RelativeSource="{RelativeSource Mode=FindAncestor,
            AncestorType={x:Type TabControl}}" />
                    <Binding RelativeSource="{RelativeSource Mode=FindAncestor,
            AncestorType={x:Type TabControl}}" Path="ActualWidth" />
                </MultiBinding>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>
 45
Author: Ryan Versaw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-31 05:20:46

Wydaje się, że każdy podąża trasą konwertera, ale tak naprawdę jest to tak proste, jak użycie UniformGrid z Rows ustawionym na 1 w szablonie TabControl, zamiast TabPanel. Oczywiście będziesz musiał zmienić szablon, ale nie jest to takie złe.

 18
Author: Charlie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-26 00:07:24

Udało mi się to zrobić używając takiego konwertera:

namespace WpfApplication1.Converters
{
    public class SizeConverter : IValueConverter
    {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
            double width = Double.Parse(value.ToString());
            //Subtract 1, otherwise we could overflow to two rows.
            return .25 * width - 1;
        }

        public object ConvertBack(object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
            throw new NotSupportedException();
        }

        #endregion
    }
}

Następnie dodanie przestrzeni nazw do mojego xaml:

xmlns:local="clr-namespace:WpfApplication1.Converters"

Następnie wykonanie wszystkich Tabitemów za pomocą konwertera:

<Window.Resources>
        <local:SizeConverter x:Key="sizeConverter" />
        <Style TargetType="{x:Type TabItem}">
            <Setter Property="Width" Value="{Binding ElementName=x_Grid, Path=ActualWidth, Converter={StaticResource sizeConverter}}" />
        </Style>
    </Window.Resources>

X_Grid to X: Nazwa elementu nadrzędnego, którego tabulatory mają być 1/4, jeśli to ma sens.

 6
Author: Jordan H.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-29 19:05:09

Jest to możliwe poprzez powiązanie szerokości z rzeczywistą szerokością kontrolki zakładki nadrzędnej, jak pokazano poniżej.

Owinąłem go w stylu, który można zastosować do wszystkich stron kart.

<Grid>
      <Grid.Resources>
        <Style TargetType="TabItem">
            <Setter Property="Width" Value="{Binding    
                     Path=ActualWidth,    
                     RelativeSource={RelativeSource    
                    Mode=FindAncestor,    
                    AncestorType={x:Type TabControl}}}"/>
        </Style>
    </Grid.Resources>

<TabControl>
    <TabItem Header="Page3"/>
    <TabItem Header="Page2"/>
    <TabItem Header="Page3"/>            
</TabControl> 
</Grid>
 3
Author: John,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-04 20:10:02

Jestem facetem w starym stylu. i wolę tego rodzaju funkcjonalność, aby zamknąć w kodzie samego sterowania. Moja pochodna Kontrola wygląda następująco:

    public class CustomTabControl :TabControl
{
    protected override void OnRenderSizeChanged(System.Windows.SizeChangedInfo sizeInfo)
    {
        foreach (TabItem item in this.Items)
        {
            double newW = (this.ActualWidth / Items.Count) - 1;
            if (newW < 0) newW = 0;

            item.Width = newW;
        }            
    }       
}

A mój XAML wygląda jak

</infrastructure:CustomTabControl>
     <TabItem />
     <TabItem />
</infrustracture:CustomControl>

Czy ktoś może wyjaśnić, dlaczego wszyscy wolą kontrolę stylizacji zamiast wyprowadzania.

 2
Author: Alex G,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-12 16:53:34

Rozwiązałem ten problem tworząc specjalny konwerter:

    public class TabItemWidthAdjustmentConverter : IValueConverter
    {
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        Double lTabControlWidth = value is Double ? (Double)value : 50; // 50 just to see something, in case of error
        Int32 lTabsCount = (parameter != null && parameter is String) ? Int32.Parse((String)parameter) : 1;
        return lTabControlWidth / lTabsCount;
    }

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

I obliczam wartość jednej zakładki w elemencie znacznika TabControl, aby uniknąć obliczania jej dla każdej zakładki osobno. Oto przykładowy kod (zauważ, że w moim przypadku potrzebowałem poziomego przewijania, ponieważ mam wiele elementów tabulacji i o minimalnej szerokości):

<TabControl Name="tabControl" VerticalAlignment="Stretch" SelectionChanged="TabControl_SelectionChanged" 
                    Tag="{Binding RelativeSource={RelativeSource Self}, Path=ActualWidth, Converter={StaticResource tabItemWidthAdjustmentConverter}, ConverterParameter=15}"><!-- Here 15 because I have 15 tabs -->
            <TabControl.Template>
                <ControlTemplate TargetType="TabControl">
                    <StackPanel>
                        <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
                            <TabPanel x:Name="HeaderPanel"
                                      Panel.ZIndex="1"
                                      KeyboardNavigation.TabIndex="1"
                                      IsItemsHost="True"/>
                        </ScrollViewer>
                        <ContentPresenter x:Name="PART_SelectedContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                          Margin="{TemplateBinding Padding}"
                                          ContentSource="SelectedContent"/>
                    </StackPanel>
                </ControlTemplate>
            </TabControl.Template>
            <TabItem Header="Tab1" MinWidth="115" VerticalAlignment="Stretch" Width="{Binding ElementName=tabControl, Path=Tag}">
                <ContentControl ContentTemplate="{StaticResource My_TemplateTab1}">
                    <ContentPresenter />
                </ContentControl>
            </TabItem>
            <TabItem Header="Tab2" MinWidth="115" Height="50" Width="{Binding ElementName=tabControl, Path=Tag}">
                <ContentControl ContentTemplate="{StaticResource My_TemplateTab2}">
                    <ContentPresenter />
                </ContentControl>
            </TabItem>
            <!-- Here another 13 tabs which I skipped -->
            </TabControl>

Mogę powiedzieć, że to działa jak urok w moim przypadku :) Mam nadzieję, że komuś się przyda!

P. S. nie potrzebowałem/chciałem w moim przypadku styl dowolny.

 1
Author: XMight,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-17 09:57:14

Oto bezbolesne rozwiązanie, które używa tylko szablonów:

<Window x:Class="Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:EffectLibrary="clr-namespace:EffectLibrary;assembly=EffectLibrary"
        mc:Ignorable="d"
        Title="Window1" Height="300" Width="300">
    <TabControl Style="{DynamicResource TabControlStyle}" ItemContainerStyle="{DynamicResource TabItemStyle}" BorderBrush="{DynamicResource Pallete.Primary}" Foreground="{DynamicResource Pallete.Primary}" Background="Transparent" Margin="0" d:LayoutOverrides="Height">
        <TabControl.Resources>
            <Style x:Key="TabControlStyle" TargetType="{x:Type TabControl}">
                <Setter Property="Padding" Value="0"/>
                <Setter Property="HorizontalContentAlignment" Value="Center"/>
                <Setter Property="VerticalContentAlignment" Value="Center"/>
                <Setter Property="Background" Value="Transparent"/>
                <Setter Property="BorderBrush" Value="#093A5F"/>
                <Setter Property="BorderThickness" Value="1"/>
                <Setter Property="Foreground" Value="#001423"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type TabControl}">
                            <Border x:Name="Bg" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
                                <Grid x:Name="templateRoot" ClipToBounds="true" SnapsToDevicePixels="true" KeyboardNavigation.TabNavigation="Local">
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition x:Name="ColumnDefinition0"/>
                                        <ColumnDefinition x:Name="ColumnDefinition1" Width="0"/>
                                    </Grid.ColumnDefinitions>
                                    <Grid.RowDefinitions>
                                        <RowDefinition x:Name="RowDefinition0" Height="Auto"/>
                                        <RowDefinition x:Name="RowDefinition1" Height="*"/>
                                    </Grid.RowDefinitions>
                                    <UniformGrid x:Name="headerPanel" IsItemsHost="True" Margin="0">
                                        <UniformGrid.Style>
                                            <Style TargetType="{x:Type UniformGrid}">
                                                <Setter Property="Rows" Value="1"/>
                                                <Style.Triggers>
                                                    <DataTrigger Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource TemplatedParent}}" Value="Right">
                                                        <Setter Property="Columns" Value="1"/>
                                                        <Setter Property="Rows" Value="0"/>
                                                    </DataTrigger>
                                                    <DataTrigger Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource TemplatedParent}}" Value="Left">
                                                        <Setter Property="Columns" Value="1"/>
                                                        <Setter Property="Rows" Value="0"/>
                                                    </DataTrigger>
                                                </Style.Triggers>
                                            </Style>
                                        </UniformGrid.Style>
                                    </UniformGrid>
                                    <Border x:Name="contentPanel" Grid.Column="0" KeyboardNavigation.DirectionalNavigation="Contained" Grid.Row="1" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local" BorderThickness="0,1,0,0" BorderBrush="{TemplateBinding BorderBrush}">
                                        <ContentPresenter x:Name="PART_SelectedContentHost" ContentSource="SelectedContent" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                                    </Border>
                                </Grid>
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="TabStripPlacement" Value="Bottom">
                                    <Setter Property="Grid.Row" TargetName="headerPanel" Value="1"/>
                                    <Setter Property="Grid.Row" TargetName="contentPanel" Value="0"/>
                                    <Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
                                    <Setter Property="Height" TargetName="RowDefinition1" Value="Auto"/>
                                </Trigger>
                                <Trigger Property="TabStripPlacement" Value="Left">
                                    <Setter Property="Grid.Row" TargetName="headerPanel" Value="0"/>
                                    <Setter Property="Grid.Row" TargetName="contentPanel" Value="0"/>
                                    <Setter Property="Grid.Column" TargetName="headerPanel" Value="0"/>
                                    <Setter Property="Grid.Column" TargetName="contentPanel" Value="1"/>
                                    <Setter Property="Width" TargetName="ColumnDefinition0" Value="Auto"/>
                                    <Setter Property="Width" TargetName="ColumnDefinition1" Value="*"/>
                                    <Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
                                    <Setter Property="Height" TargetName="RowDefinition1" Value="0"/>
                                </Trigger>
                                <Trigger Property="TabStripPlacement" Value="Right">
                                    <Setter Property="Grid.Row" TargetName="headerPanel" Value="0"/>
                                    <Setter Property="Grid.Row" TargetName="contentPanel" Value="0"/>
                                    <Setter Property="Grid.Column" TargetName="headerPanel" Value="1"/>
                                    <Setter Property="Grid.Column" TargetName="contentPanel" Value="0"/>
                                    <Setter Property="Width" TargetName="ColumnDefinition0" Value="*"/>
                                    <Setter Property="Width" TargetName="ColumnDefinition1" Value="Auto"/>
                                    <Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
                                    <Setter Property="Height" TargetName="RowDefinition1" Value="0"/>
                                </Trigger>
                                <Trigger Property="IsEnabled" Value="false">
                                    <Setter Property="Effect" TargetName="templateRoot">
                                        <Setter.Value>
                                            <EffectLibrary:DesaturateEffect DesaturationFactor=".25"/>
                                        </Setter.Value>
                                    </Setter>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
            <Style x:Key="TabItemStyle" TargetType="{x:Type TabItem}">
                <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
                <Setter Property="Foreground" Value="{Binding Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabControl}}}"/>
                <Setter Property="Background" Value="{Binding Background, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabControl}}}"/>
                <Setter Property="BorderBrush" Value="{Binding BorderBrush, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabControl}}}"/>
                <Setter Property="Margin" Value="0"/>
                <Setter Property="Padding" Value="0,5"/>
                <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                <Setter Property="VerticalContentAlignment" Value="Stretch"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type TabItem}">
                            <Grid x:Name="templateRoot" SnapsToDevicePixels="true"  Background="{TemplateBinding Background}">
                                <Border x:Name="mainBorder" BorderBrush="{TemplateBinding BorderBrush}">
                                    <Border x:Name="highlightBorder"/>
                                </Border>
                                <ContentPresenter x:Name="contentPresenter" ContentSource="Header" Focusable="False" HorizontalAlignment="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
                            </Grid>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsEnabled" Value="false">
                                    <Setter Property="Effect" TargetName="templateRoot">
                                        <Setter.Value>
                                            <EffectLibrary:DesaturateEffect DesaturationFactor=".25"/>
                                        </Setter.Value>
                                    </Setter>
                                </Trigger>
                                <DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="true">
                                    <Setter TargetName="highlightBorder" Property="Background" Value="#0B79CE"/>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Value="Top">
                                    <Setter TargetName="mainBorder" Property="BorderThickness" Value="0,0,1,0"/>
                                    <Setter TargetName="highlightBorder" Property="Height" Value="2"/>
                                    <Setter TargetName="highlightBorder" Property="VerticalAlignment" Value="Bottom"/>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Value="Bottom">
                                    <Setter TargetName="mainBorder" Property="BorderThickness" Value="0,0,1,0"/>
                                    <Setter TargetName="highlightBorder" Property="Height" Value="2"/>
                                    <Setter TargetName="highlightBorder" Property="VerticalAlignment" Value="Top"/>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Value="Left">
                                    <Setter TargetName="mainBorder" Property="BorderThickness" Value="0,0,0,1"/>
                                    <Setter TargetName="highlightBorder" Property="Width" Value="2"/>
                                    <Setter TargetName="highlightBorder" Property="HorizontalAlignment" Value="Right"/>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Value="Right">
                                    <Setter TargetName="mainBorder" Property="BorderThickness" Value="0,0,0,1"/>
                                    <Setter TargetName="highlightBorder" Property="Width" Value="2"/>
                                    <Setter TargetName="highlightBorder" Property="HorizontalAlignment" Value="Left"/>
                                </DataTrigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </TabControl.Resources>
        <TabItem Header="Years">
            <ListBox Background="{DynamicResource Pallete.Primary.Brightest}" Foreground="{DynamicResource Pallete.Primary}">
                <TextBlock Text="2015"/>
                <TextBlock Text="2016"/>
                <TextBlock Text="2017"/>
            </ListBox>
        </TabItem>
        <TabItem Header="Tables">
            <ListBox  Background="{DynamicResource Pallete.Primary.Brightest}" Foreground="{DynamicResource Pallete.Primary}">
                <TextBlock Text="Table1..."/>
                <TextBlock Text="Table2..."/>
                <TextBlock Text="Table3..."/>
            </ListBox>
        </TabItem>
    </TabControl>
</Window>

Mam nadzieję, że włączyłem wszystkie kolory i będzie działać dla Ciebie. Ahh... Pstryk! Mój Efekt Desaturacji! Mój projekt startowy WPF możesz pobrać ten efekt stamtąd, jeśli chcesz (łatwiej jest rzucić efekt w wyzwalaczu, niż przebarwić wszystko, tak samo z podświetleniami). Tak, to dużo kodu, ale po prostu zmieniłem ItemsContainer, aby wyglądał lepiej i zastąpiłem standardową kontrolę nagłówka UniformGrid I set Rows lub Kolumny do 1 w zależności od TabStripPlacement. Teraz mogę zwinąć ten kod, albo gdzieś go ukryć. :)

 1
Author: zORg Alex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-21 09:52:44

Podążałem za sugestią Charliego i ruszyłem na drogę re-template. Oto prosta implementacja TabControl, która dzieli dostępną przestrzeń równo między swoje TabItem s, używając UniformGrid:

Control ' s XAML

<TabControl x:Class="YourNamespace.Views.BigTabsTabControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:YourNamespace.Views"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
            Padding="2" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
            BorderThickness="1" Foreground="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}">

    <TabControl.Resources>
        <SolidColorBrush x:Key="TabItem.Selected.Background" Color="#FFFFFF"/>
        <SolidColorBrush x:Key="TabItem.Selected.Border" Color="#ACACAC"/>
    </TabControl.Resources>

    <TabControl.Style>
        <Style TargetType="{x:Type TabControl}">
            <Setter Property="Background" Value="{StaticResource TabItem.Selected.Background}"/>
            <Setter Property="BorderBrush" Value="{StaticResource TabItem.Selected.Border}"/>
        </Style>
    </TabControl.Style>

    <TabControl.Template>
        <ControlTemplate TargetType="{x:Type TabControl}">
            <Grid x:Name="templateRoot" ClipToBounds="true" SnapsToDevicePixels="true" KeyboardNavigation.TabNavigation="Local">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition x:Name="ColumnDefinition0"/>
                    <ColumnDefinition x:Name="ColumnDefinition1" Width="0"/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition x:Name="RowDefinition0" Height="Auto"/>
                    <RowDefinition x:Name="RowDefinition1" Height="*"/>
                </Grid.RowDefinitions>

                <UniformGrid x:Name="headerPanel" Background="Transparent" Grid.Column="0" IsItemsHost="true" Grid.Row="0" KeyboardNavigation.TabIndex="1" Panel.ZIndex="1" />
                <Border x:Name="contentPanel" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Column="0" KeyboardNavigation.DirectionalNavigation="Contained" Grid.Row="1" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local">
                    <ContentPresenter x:Name="PART_SelectedContentHost" ContentSource="SelectedContent" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                </Border>
            </Grid>
            <ControlTemplate.Triggers>
                <Trigger Property="TabStripPlacement" Value="Bottom">
                    <Setter Property="Grid.Row" TargetName="headerPanel" Value="1"/>
                    <Setter Property="Grid.Row" TargetName="contentPanel" Value="0"/>
                    <Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
                    <Setter Property="Height" TargetName="RowDefinition1" Value="Auto"/>
                    <Setter Property="Margin" TargetName="headerPanel" Value="2,0,2,2"/>
                </Trigger>
                <Trigger Property="TabStripPlacement" Value="Left">
                    <Setter Property="Grid.Row" TargetName="headerPanel" Value="0"/>
                    <Setter Property="Grid.Row" TargetName="contentPanel" Value="0"/>
                    <Setter Property="Grid.Column" TargetName="headerPanel" Value="0"/>
                    <Setter Property="Grid.Column" TargetName="contentPanel" Value="1"/>
                    <Setter Property="Width" TargetName="ColumnDefinition0" Value="Auto"/>
                    <Setter Property="Width" TargetName="ColumnDefinition1" Value="*"/>
                    <Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
                    <Setter Property="Height" TargetName="RowDefinition1" Value="0"/>
                    <Setter Property="Margin" TargetName="headerPanel" Value="2,2,0,2"/>
                </Trigger>
                <Trigger Property="TabStripPlacement" Value="Right">
                    <Setter Property="Grid.Row" TargetName="headerPanel" Value="0"/>
                    <Setter Property="Grid.Row" TargetName="contentPanel" Value="0"/>
                    <Setter Property="Grid.Column" TargetName="headerPanel" Value="1"/>
                    <Setter Property="Grid.Column" TargetName="contentPanel" Value="0"/>
                    <Setter Property="Width" TargetName="ColumnDefinition0" Value="*"/>
                    <Setter Property="Width" TargetName="ColumnDefinition1" Value="Auto"/>
                    <Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
                    <Setter Property="Height" TargetName="RowDefinition1" Value="0"/>
                    <Setter Property="Margin" TargetName="headerPanel" Value="0,2,2,2"/>
                </Trigger>
                <Trigger Property="IsEnabled" Value="false">
                    <Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </TabControl.Template>
</TabControl>

Kod kontrolny-za

using System.Windows.Controls;
using System.Windows.Controls.Primitives;

namespace YourNamespace.Views
{
  /// <summary>
  /// A TabControl with large tabs. 
  /// </summary>
  public partial class BigTabsTabControl : TabControl
  {
    public BigTabsTabControl()
    {
      InitializeComponent();
    }

    public override void OnApplyTemplate()
    {
      base.OnApplyTemplate();

      if (this.Template != null)
      {
        UniformGrid X = this.Template.FindName("headerPanel", this) as UniformGrid;
        if (X != null) X.Columns = this.Items.Count;
      }
    }
  }
}

To jest to. Możesz teraz dodać TabItem s do tej kontrolki, a ich szerokość zostanie automatycznie dostosowana. Nie trzeba też określać Grid.Column dla tych TabItem s, działają bez niego dobrze, nawet w czasie projektowania.

 1
Author: dotNET,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-07 07:32:00

Nie wiem, czy to zadziała dla tabs, ale kiedy potrzebowałem rozciągnąć cokolwiek do wypełnienia kontenera, używałem ViewBox . Tego właśnie szukasz?

 0
Author: Matthew Steeples,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-01 16:05:21

Oprócz rozwiązania Ryana Versawa accecpted, które daje równe szerokości nagłówka tabItem, znalazłem następujący sposób, aby uzależnić go od długości każdego nagłówka.

Najpierw otrzymujemy łańcuch każdego nagłówka tabItem dodając tę linię do multibindingu xaml. W ten sposób staje się:

<MultiBinding Converter="{StaticResource tabSizeConverter}">
           <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type TabControl}}" />
           <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type TabControl}}" Path="ActualWidth" />
           <Binding Path="Header" RelativeSource="{RelativeSource Self}"/>
</MultiBinding>

I trochę więcej kodu w konwerterze (wartości [] otrzymuje również nagłówek tabItem):

public object Convert(object[] values, Type targetType, object parameter,
        System.Globalization.CultureInfo culture)
    {
        TabControl tabControl = values[0] as TabControl;

        string AllHeaders = "";
        for (int i = 0; i < tabControl.Items.Count; i++)
        {
            int index = tabControl.Items[i].ToString().IndexOf("Header:") + "Header:".Length;
            string currentHeader = tabControl.Items[i].ToString().Substring(index);
            currentHeader = currentHeader.Substring(0, currentHeader.Length - " Content:".Length);
            AllHeaders += currentHeader;
        }

        //Normalize width according to header length
        double width = values[2].ToString().Length * tabControl.ActualWidth / AllHeaders.Length;

        //Subtract 1, otherwise we could overflow to two rows.
        var retVal = (width <= 1) ? 0 : (width - 1);
        return retVal;
    }

Podejrzewam, że może być bardziej skuteczny sposób, aby uzyskać ciąg AllHeaders wszystkich nagłówków, ale działa dobrze tak jak jest ...

 0
Author: tombobadil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-12 13:06:22

Używam następującego rozwiązania: W oknie głównym używam zdarzenia zmiany rozmiaru okna i na tabcontrol Inicjalizowanego zdarzenia, aby ustawić szerokość każdej zakładki. Liczba " 5 " odpowiada mojej liczbie kart.

    private void tabchanger_Initialized(object sender, EventArgs e)
    {
        foreach (TabItem item in tabchanger.Items)
        {
            double newW = (tabchanger.ActualWidth / 5) - 1;
            if (newW < 0) newW = 0;

            item.Width = newW;
        }

    }

    private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        foreach (TabItem item in tabchanger.Items)
        {
            double newW = (tabchanger.ActualWidth / 5) - 1;
            if (newW < 0) newW = 0;

            item.Width = newW;
        }
    }
 0
Author: hyphestos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-21 18:13:17