Установка цвета фона неактивных вкладок WPF TabControl - PullRequest
2 голосов
/ 17 марта 2010

Есть ли простой способ установить кисть фона для всех неактивных вкладок в WPF TabControl? Я хочу эмулировать внешний вид VS 2010 на TabControl - цвет фона неактивных вкладок элемента управления должен соответствовать цвету фона окна, в котором расположен TabControl, так что вы видите только текст вкладки, а не сама вкладка.

Я знаю, что для этого потребуется ControlTemplate; Я пытаюсь выяснить, что положить в шаблоне управления. Другими словами, как мне указать, что конкретная кисть должна применяться ко всем неактивным вкладкам? Спасибо за вашу помощь.

Ответы [ 2 ]

6 голосов
/ 17 марта 2010

Вот решение: как сказал Стивен, добавьте триггер к шаблону элемента управления. На самом деле это триггер свойства, и его нужно установить только для неактивного состояния. Таким образом, мы устанавливаем триггер для IsSelected = false . Мы нацеливаем границу (Bd в шаблоне управления по умолчанию для TabItem) для TabItem и устанавливаем для Background желаемый цвет (я использую RelativeSource FindAncestor для соответствия сетке, на которой находится вкладка помещенный). Затем мы устанавливаем Bd s BorderThickness на 0, и все готово:

<Trigger Property="IsSelected" Value="false">
    <Setter Property="Background" TargetName="Bd" Value="{Binding Path=Background, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Grid}}}"/>
    <Setter Property="BorderThickness" TargetName="Bd" Value="0" />
</Trigger>

Я поместил триггер в шаблон по умолчанию, чуть ниже IsSelected = true триггер.

Обратите внимание, что триггер жестко запрограммирован для поиска предка Grid в качестве источника неактивного цвета фона вкладки (AncestorType={x:Type Grid}). Это потому, что я установил фон моего просмотра в Grid, который я использую в качестве корня макета. Вам нужно будет изменить AncestorType, если вы используете другой корневой элемент управления макета или если вы устанавливаете цвет фона вашего представления в другом месте (например, в теге <Window>).

Кстати, вы также можете использовать триггер IsSelected = true , чтобы изменить Background заголовка активной вкладки с белого на цвет фона TabControl:

<Trigger Property="IsSelected" Value="true">
    <Setter Property="Panel.ZIndex" Value="1"/>
    <Setter Property="Background" TargetName="Bd" Value="{Binding Path=Background, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabControl}}}"/>
</Trigger>

Для тех, кому нравится это визуальное представление, вот полный шаблон управления. Он будет применен автоматически к любому TabControl в пределах его видимости. Просто добавьте эту разметку в раздел окна XAML (или импортируйте ее из ResourceDictionary), и ваш TabControl получит внешний вид VS 2010. Не забудьте изменить FindAncestor proeprty, чтобы шаблон нашел правильный цвет фона.

<!-- Styles for FS TabItem Control Template-->
<Style x:Key="TabItemFocusVisual">
    <Setter Property="Control.Template">
        <Setter.Value>
            <ControlTemplate>
                <Rectangle Stroke="Black" StrokeDashArray="1 2" StrokeThickness="1" Margin="3,3,3,1" SnapsToDevicePixels="true"/>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
<SolidColorBrush x:Key="TabControlNormalBorderBrush" Color="#8C8E94"/>
<LinearGradientBrush x:Key="ButtonNormalBackground" EndPoint="0,1" StartPoint="0,0">
    <GradientStop Color="#F3F3F3" Offset="0"/>
    <GradientStop Color="#EBEBEB" Offset="0.5"/>
    <GradientStop Color="#DDDDDD" Offset="0.5"/>
    <GradientStop Color="#CDCDCD" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="TabItemHotBackground" EndPoint="0,1" StartPoint="0,0">
    <GradientStop Color="#EAF6FD" Offset="0.15"/>
    <GradientStop Color="#D9F0FC" Offset=".5"/>
    <GradientStop Color="#BEE6FD" Offset=".5"/>
    <GradientStop Color="#A7D9F5" Offset="1"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="TabItemSelectedBackground" Color="#F9F9F9"/>
<SolidColorBrush x:Key="TabItemHotBorderBrush" Color="#3C7FB1"/>
<SolidColorBrush x:Key="TabItemDisabledBackground" Color="#F4F4F4"/>
<SolidColorBrush x:Key="TabItemDisabledBorderBrush" Color="#FFC9C7BA"/>

<!-- FS TabItem Control Template-->
<Style TargetType="{x:Type TabItem}">
    <Setter Property="FocusVisualStyle" Value="{StaticResource TabItemFocusVisual}"/>
    <Setter Property="Foreground" Value="Black"/>
    <Setter Property="Padding" Value="6,1,6,1"/>
    <Setter Property="BorderBrush" Value="{StaticResource TabControlNormalBorderBrush}"/>
    <Setter Property="Background" Value="{StaticResource ButtonNormalBackground}"/>
    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
    <Setter Property="VerticalContentAlignment" Value="Stretch"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TabItem}">
                <Grid SnapsToDevicePixels="true">
                    <Border x:Name="Bd" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1,1,1,0" Padding="{TemplateBinding Padding}">
                        <ContentPresenter x:Name="Content" HorizontalAlignment="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" VerticalAlignment="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" ContentSource="Header" RecognizesAccessKey="True"/>
                    </Border>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="true">
                        <Setter Property="Background" TargetName="Bd" Value="{StaticResource TabItemHotBackground}"/>
                    </Trigger>
                    <Trigger Property="IsSelected" Value="true">
                        <Setter Property="Panel.ZIndex" Value="1"/>
                        <Setter Property="Background" TargetName="Bd" Value="{Binding Path=Background, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabControl}}}"/>
                    </Trigger>
                    <Trigger Property="IsSelected" Value="false">
                        <Setter Property="Background" TargetName="Bd" Value="{Binding Path=Background, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Grid}}}"/>
                        <Setter Property="BorderThickness" TargetName="Bd" Value="0" />
                    </Trigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsSelected" Value="false"/>
                            <Condition Property="IsMouseOver" Value="true"/>
                        </MultiTrigger.Conditions>
                        <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource TabItemHotBorderBrush}"/>
                    </MultiTrigger>
                    <Trigger Property="TabStripPlacement" Value="Bottom">
                        <Setter Property="BorderThickness" TargetName="Bd" Value="1,0,1,1"/>
                    </Trigger>
                    <Trigger Property="TabStripPlacement" Value="Left">
                        <Setter Property="BorderThickness" TargetName="Bd" Value="1,1,0,1"/>
                    </Trigger>
                    <Trigger Property="TabStripPlacement" Value="Right">
                        <Setter Property="BorderThickness" TargetName="Bd" Value="0,1,1,1"/>
                    </Trigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsSelected" Value="true"/>
                            <Condition Property="TabStripPlacement" Value="Top"/>
                        </MultiTrigger.Conditions>
                        <Setter Property="Margin" Value="-2,-2,-2,-1"/>
                        <Setter Property="Margin" TargetName="Content" Value="0,0,0,1"/>
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsSelected" Value="true"/>
                            <Condition Property="TabStripPlacement" Value="Bottom"/>
                        </MultiTrigger.Conditions>
                        <Setter Property="Margin" Value="-2,-1,-2,-2"/>
                        <Setter Property="Margin" TargetName="Content" Value="0,1,0,0"/>
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsSelected" Value="true"/>
                            <Condition Property="TabStripPlacement" Value="Left"/>
                        </MultiTrigger.Conditions>
                        <Setter Property="Margin" Value="-2,-2,-1,-2"/>
                        <Setter Property="Margin" TargetName="Content" Value="0,0,1,0"/>
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsSelected" Value="true"/>
                            <Condition Property="TabStripPlacement" Value="Right"/>
                        </MultiTrigger.Conditions>
                        <Setter Property="Margin" Value="-1,-2,-2,-2"/>
                        <Setter Property="Margin" TargetName="Content" Value="1,0,0,0"/>
                    </MultiTrigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Background" TargetName="Bd" Value="{StaticResource TabItemDisabledBackground}"/>
                        <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource TabItemDisabledBorderBrush}"/>
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
1 голос
/ 17 марта 2010

Да. Определите кисти, а затем в своем стиле для вкладки, используйте триггер для его активного состояния, и когда он АКТИВЕН, установите его на одну кисть, а когда триггер срабатывает, потому что он неактивен, установите его на другой.

Это можно сделать полностью в XAML.

...