简体   繁体   中英

Stretch TabItem to TabControl Width

I'm pretty new to WPF and I'm not sure how I should proceed, I have a TabControl with some TabItems, I would like to get the whole TabControl width divided equally so the TabItems get the same space.

I have implemented this solution and it didn't work, means that the tabs are not getting the whole width of the Parent TabControl when I'm using Generic TabControls, but it works when I use the Custom TabControl.

My question is, Do I have something wrong on the Generic TabControl implementation? Or do I have to go with the Custom TabControl?

Following the xaml Code with the generic TabControl

<Window x:Class="Project.GUI.MainWindow.MainWindowView"
        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:converters="clr-namespace:Project.GUI.Helpers"
        mc:Ignorable="d"
        Height="1000"
        Width="1000"
        ResizeMode="CanResizeWithGrip"
        WindowState="Maximized"
        WindowStyle="None"
        WindowStartupLocation="CenterOwner">
    <Window.Resources>
        <converters: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>
        <Style x:Key="TabItemTitle">
            <Setter Property="Control.FontFamily"
                    Value="Century Gothic" />
            <Setter Property="Control.FontSize"
                    Value="20px" />
            <Setter Property="Control.Background"
                    Value="#348781" />
        </Style>

    </Window.Resources>

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="3*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <TabControl Grid.Row="0"
                    Grid.Column="1"
                    Grid.RowSpan="2"
                    Width="Auto"
                    Name="TabControl">
            <TabItem Header="Patient"
                     Height="100"
                     Style="{StaticResource TabItemTitle}" />
            <TabItem Header="Läsion"
                     Height="100"
                     Style="{StaticResource TabItemTitle}" />
            <TabItem Header="Scan"
                     Height="100"
                     Style="{StaticResource TabItemTitle}" />
            <TabItem Header="Analyse"
                     Height="100"
                     Style="{StaticResource TabItemTitle}" />
            <TabItem Header="Report"
                     Height="100"
                     Style="{StaticResource TabItemTitle}" />
        </TabControl>
    </Grid>
</Window>

Converter class:

/// <summary>
/// The tab size converter.
/// </summary>
public class TabSizeConverter : IMultiValueConverter
{
    /// <summary>
    /// The convert.
    /// </summary>
    /// <param name="values">
    /// The values.
    /// </param>
    /// <param name="targetType">
    /// The target type.
    /// </param>
    /// <param name="parameter">
    /// The parameter.
    /// </param>
    /// <param name="culture">
    /// The culture.
    /// </param>
    /// <returns>
    /// The <see cref="object"/>.
    /// </returns>
    public object Convert(object[] values, Type targetType, object parameter, 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;
    }

    /// <summary>
    /// The convert back.
    /// </summary>
    /// <param name="value">
    /// The value.
    /// </param>
    /// <param name="targetTypes">
    /// The target types.
    /// </param>
    /// <param name="parameter">
    /// The parameter.
    /// </param>
    /// <param name="culture">
    /// The culture.
    /// </param>
    /// <returns>
    /// The <see cref="object[]"/>.
    /// </returns>
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) =>
        throw new NotSupportedException();
}

Here my code for the Custom TabControl

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Project"
    xmlns:custom="clr-namespace:Project.GUI.Custom">
   
    <Style TargetType="{x:Type custom:CustomTabControl}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type custom:CustomTabControl}">
                    <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
                        <TabControl>
                            <TabItem Header="Patient"
                                     Height="100"/>
                            <TabItem Header="Lesion"
                                     Height="100"
                                      />
                            <TabItem Header="Scan"
                                     Height="100"
                                      />
                            <TabItem Header="Analyse"
                                     Height="100"
                                      />
                            <TabItem Header="Report"
                                     Height="100"
                                      />
                        </TabControl>
                    </Border>
                    
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

Thanks for your time.

Solved, problem was the using of different Styles, fixed by the following:

<Style TargetType="{x:Type TabItem}">
            <Setter Property="FontFamily"
                    Value="Century Gothic" />
            <Setter Property="FontSize"
                    Value="20px" />
            <Setter Property="Background"
                    Value="#348781" />
            <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>

TabSizeConverter is applied in default <Style TargetType="{x:Type TabItem}"> style.

TabItems use TabItemTitle :

<TabItem Header="Patient"
         Height="100"
         Style="{StaticResource TabItemTitle}" />

of course TabSizeConverter is not applied.

use base style instead:

<TabItem Header="Patient" Height="100"/>

or merge two styles into one:

<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>

    <Setter Property="Control.FontFamily"
            Value="Century Gothic" />
    <Setter Property="Control.FontSize"
            Value="20px" />
    <Setter Property="Control.Background"
            Value="#348781" />
</Style>

if named style is required, add x:Key="TabItemTitle" attribute to Style

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM