Как изменить порядок перекрытия TabItems в WPF TabControl - PullRequest
4 голосов
/ 14 января 2011

Я создал вертикальные TabItems с объектом Path.Выбранный TabItem перекрывает невыбранные TabItems, это прекрасно работает.Перекрытие выполняется путем установки отрицательного поля в шаблоне TabItem.

Для невыбранных элементов TabItem сейчас TabItem перекрывается с помощью TabItem ниже.Например, на рисунке вкладка 4 перекрывает вкладку 3, а вкладка 3 перекрывает вкладку 2.

Я хотел бы изменить порядок наложения для невыбранных элементов вкладки, чтобы невыбранный элемент TabItem перекрывал элемент TabItem ниже и перекрывался с помощьюTabItem выше, например Tab 2 перекрывает Tab 3 и Tab 3 перекрывает Tab 4.

Я попытался установить свойство FlowDirection для TabPanel, но это не работает.

Как я могудостичь этого?Любая помощь приветствуется.Заранее спасибо!

Неправильное перекрытие невыбранных TabItems:

Vertical TabItems

XAML-код:

<Style x:Key="styleMainNavTabControl" TargetType="{x:Type TabControl}">
    <Setter Property="TabStripPlacement" Value="Left" />
    <Setter Property="SnapsToDevicePixels" Value="true"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TabControl}">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="200"/>
                    </Grid.ColumnDefinitions>
                    <Border Grid.Column="0" Background="White" BorderBrush="Black" BorderThickness="0,0,1,0" Padding="20">
                        <ContentPresenter ContentSource="SelectedContent" />
                    </Border>
                    <Border Grid.Column="1" Padding="0,30,10,0" Background="#F7F3F7">
                        <TabPanel Panel.ZIndex="1" Margin="-1,0,0,0" FlowDirection="RightToLeft" IsItemsHost="True" Background="Transparent"/>
                    </Border>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
<Style x:Key="styleMainNavTabItem" TargetType="{x:Type TabItem}">
    <Setter Property="MinHeight" Value="90" />
    <Setter Property="FontSize" Value="14" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TabItem}">
                <Grid Margin="0,0,0,-35">
                    <Path Name="TabPath" Stroke="Black" StrokeThickness="1" Fill="LightGray" Data="M 0,0 a 10,10 0 0 0 10,10 h 150 a 20,20 0 0 1 20,20 v 60 a 20,20 0 0 1 -20,20 h -150 a 10,10 0 0 0 -10,10 z" />
                    <ContentPresenter ContentSource="Header" Margin="10,2,10,2" VerticalAlignment="Center" TextElement.Foreground="#FF000000"/>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter Property="Panel.ZIndex" Value="100" />
                        <Setter TargetName="TabPath" Property="Fill" Value="White" />
                        <Setter TargetName="TabPath" Property="Data" Value="M 0,0 a 10,10 0 0 0 10,10 h 150 a 20,20 0 0 1 20,20 v 60 a 20,20 0 0 1 -20,20 h -150 a 10,10 0 0 0 -10,10" />
                    </Trigger>
                    <Trigger Property="IsSelected" Value="False">
                        <Setter Property="Panel.ZIndex" Value="90" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>

1 Ответ

3 голосов
/ 15 января 2011

Я думаю, что самый простой способ сделать это с MultiBinding / Converter, который использует родительский ItemsContainerGenerator для определения ZIndex.Это будет выглядеть примерно так:

public class TabZIndexConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var tabItem = values[0] as TabItem;
        var tabControl = values[1] as TabControl;
        if (tabItem == null || tabControl == null) return Binding.DoNothing;

        var count = (int)values[2];

        var index = tabControl.ItemContainerGenerator.IndexFromContainer(tabItem);

        return count - index;
    }

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

Затем вы измените свой стиль TabItem, чтобы установить ZIndex в установщике (и удалите второй триггер, так как он отключит этот установщик):

<Style x:Key="styleMainNavTabItem" TargetType="{x:Type TabItem}">
    <Setter Property="Panel.ZIndex">
        <Setter.Value>
            <MultiBinding Converter="{StaticResource tabZIndexConverter}">
                <Binding RelativeSource="{RelativeSource Self}" />
                <Binding RelativeSource="{RelativeSource AncestorType={x:Type TabControl}}" />
                <Binding Path="Items.Count" RelativeSource="{RelativeSource AncestorType={x:Type TabControl}}" />
            </MultiBinding>
        </Setter.Value>
    </Setter>
    ...
</Style>
...