WPF специализированный TabControl

Я должен разработать специализированное управление вкладкой и решенный для создания его с WPF/XAML, потому что я запланировал изучить это так или иначе. Должно быть похожим на это, когда это закончено:

Target

Я добился существенного прогресса до сих пор, но существует две оставленные проблемы:

  1. Только первый/последний объект вкладки должен иметь округленный верхний левый/нижний левый угол. Действительно ли возможно изменить стиль этих объектов, подобных способу, которым я сделал с выбранным объектом вкладки?

  2. Выбранный объект вкладки не должен иметь границы на своей правой стороне. Я пытался выполнить это с z-индексом и наложением, но результаты были довольно неутешительны. Там какой-либо другой путь состоит в том, чтобы сделать это?

Current

XAML:

<Window x:Class="MyProject.TestWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TestWindow" Height="350" Width="500" Margin="5" Background="LightGray">
<Window.Resources>
    <LinearGradientBrush x:Key="SelectedBorderBrush" StartPoint="0,0" EndPoint="1,0">
        <GradientBrush.GradientStops>
            <GradientStopCollection>
                <GradientStop Color="Gray" Offset="0.965"/>
                <GradientStop Color="WhiteSmoke" Offset="1.0"/>
            </GradientStopCollection>
        </GradientBrush.GradientStops>
    </LinearGradientBrush>
    <Style TargetType="{x:Type TabControl}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TabControl}">
                    <DockPanel>
                        <Border
                            Panel.ZIndex="50"
                            Margin="0,100,-1,0" 
                            Background="#FFAAAAAA"
                            BorderBrush="Gray"
                            CornerRadius="7,0,0,7"
                            BorderThickness="1">
                            <TabPanel
                                Margin="0,0,0,0"
                                IsItemsHost="True" />
                        </Border>
                        <Border
                            Background="WhiteSmoke"
                            BorderBrush="Gray"
                            BorderThickness="1"
                            CornerRadius="7,7,7,0" >
                            <ContentPresenter 
                                ContentSource="SelectedContent" />
                        </Border>
                    </DockPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <Style TargetType="{x:Type TabItem}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TabItem}">
                    <Grid>
                        <Border Name="Border" 
                            Background="#FFAAAAAA"
                            CornerRadius="7,0,0,0"
                            BorderBrush="Gray"
                            BorderThickness="0,0,0,1"
                            Panel.ZIndex="50"
                            Margin="0,0,0,0"
                                >

                            <ContentPresenter x:Name="ContentSite"             
                                VerticalAlignment="Center"
                                HorizontalAlignment="Left"
                                ContentSource="Header"
                                Margin="10,10,10,10"/>
                        </Border>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter Property="Panel.ZIndex" Value="100" />
                            <Setter Property="Margin" Value="0,0,-2,0" />
                            <Setter TargetName="Border" 
                                    Property="BorderBrush" 
                                    Value="{StaticResource SelectedBorderBrush}"/>
                            <Setter TargetName="Border" 
                                Property="Background" 
                                Value="WhiteSmoke" />
                            <Setter TargetName="Border" 
                                Property="CornerRadius" 
                                Value="0,0,0,0" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>
<Grid>
    <TabControl Name="_menuTabControl" TabStripPlacement="Left" Margin="5">
        <TabItem Name="_tabItem1" Header="First Tab Item" ></TabItem>

        <TabItem Name="_tabItem2" Header="Second Tab Item" >
            <Grid />
        </TabItem>
        <TabItem Name="_tabItem3" Header="Third Tab Item" >
            <Grid />
        </TabItem>
    </TabControl>
</Grid>

Править: Благодаря Vlad я мог решить вторую проблему с кистью границы градиента. Посмотрите обновления XAML для решения.

Править: Vlad решил первую проблему.

12
задан xsl 14 April 2010 в 13:07
поделиться

1 ответ

Что касается второй проблемы, возможно, вам стоит попробовать удалить отсечение ? Однако остерегайтесь возможных проблем .

Для первой проблемы вы должны попробовать триггер в стиле для свойства IsSelected . (Изменить: я вижу, вы делаете это именно так.) Посмотрите, как это реализовано в шаблоне по умолчанию в MSDN . Обратите внимание, что они также используют ZIndex .

Изменить :
Я нашел способ решения вашей первой / последней проблемы с вкладкой.Вам необходимо использовать присоединенные свойства для обозначения первой / последней вкладки:

В вашем классе TestWindow вы определяете присоединенное свойство:

public static bool GetIsFirstTab(DependencyObject obj)
{
    return (bool)obj.GetValue(IsFirstTabProperty);
}

public static void SetIsFirstTab(DependencyObject obj, bool value)
{
    obj.SetValue(IsFirstTabProperty, value);
}

public static readonly DependencyProperty IsFirstTabProperty =
        DependencyProperty.RegisterAttached("IsFirstTab", typeof(bool),
               typeof(TestWindow), new UIPropertyMetadata(false));

Затем на вашей первой вкладке вы устанавливаете это свойство:

<Window x:Class="MyProject.TestWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:MyProject"
        ...
/>
    ...
    <TabItem Name="_tabItem1" Header="First Tab Item"
             local:TestWindow.IsFirstTab="true">
    </TabItem>

Затем вы должны определить триггер для него:

<Trigger Property="IsSelected" Value="True">
    <Setter TargetName="Border" 
            Property="Background" 
            Value="WhiteSmoke" />
</Trigger>
<Trigger Property="local:Window1.IsFirstTab" Value="True">
    <Setter TargetName="Border" 
            Property="Background" 
            Value="Red" />
</Trigger>

Это должно помочь.

Тот же трюк работает с последней вкладкой. Или вы можете использовать число вместо bool в качестве присоединенного свойства.

9
ответ дан 2 December 2019 в 22:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: