Установка цвета переднего плана TabItem также устанавливает цвет переднего плана TabControl - PullRequest
13 голосов
/ 21 июня 2010

У меня есть TabControl, который я обновил.TabItem имеет триггер, который срабатывает при выборе TabItem, который изменяет текст TabItem на полужирный и зеленый.У меня проблема в том, что текст в содержимом вкладки также выделен жирным и зеленым цветом.

Я могу обойти это, установив для всех элементов управления в содержимом вкладки цвет и вес шрифта.Я хочу, но я должен сделать это?Итак, я должен убедиться, что у каждого текстового блока в области содержимого есть стиль, который устанавливает цвет на черный и нормальный вес шрифта.

Как я могу установить для IsSelected части TabItem показывать зеленый цвет, но оставитьтолько содержимое вкладки?

Я пытался установить черный цвет переднего плана TabControl, но это не работает.

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

Пример кода ниже:

    <Grid>
    <Grid.Resources>
        <!-- Tab item -->
        <Style TargetType="{x:Type TabItem}">
            <Setter Property="FontSize" Value="14"/>
            <Setter Property="MinWidth" Value="200"/>
            <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TabItem}">
                        <Grid>
                            <Border Name="Border" Padding="5,2">
                                <ContentPresenter ContentSource="Header"/>
                            </Border>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="Border.IsMouseOver" Value="True"/>
                                    <Condition Property="IsSelected" Value="False"/>
                                </MultiTrigger.Conditions>
                                <Setter Property="FontWeight" Value="Bold"/>
                                <Setter Property="Foreground" Value="Black"/>
                            </MultiTrigger>

                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="Border.IsMouseOver" Value="False"/>
                                    <Condition Property="IsSelected" Value="False"/>
                                </MultiTrigger.Conditions>
                                <Setter Property="Foreground" Value="Black" />
                            </MultiTrigger>

                            <Trigger Property="IsSelected" Value="True">
                                <Setter Property="Foreground" Value="Green"/>
                                <Setter Property="FontWeight" Value="Bold"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

        <!-- Tab control -->
        <Style  TargetType="{x:Type TabControl}">
            <Setter Property="SelectedIndex" Value="0"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TabControl}">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="200" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <Border Grid.Column="0" Padding="5" Margin="0,0,5,0" CornerRadius="3">
                                <StackPanel Orientation="Vertical">
                                    <ScrollViewer VerticalScrollBarVisibility="Auto" FocusVisualStyle="{x:Null}">
                                        <TabPanel IsItemsHost="True"/>
                                    </ScrollViewer>
                                </StackPanel>
                            </Border>
                            <Border Grid.Column="1" BorderBrush="Black" BorderThickness="0">
                                <ScrollViewer VerticalScrollBarVisibility="Auto" FocusVisualStyle="{x:Null}" Padding="10,0">
                                    <ContentPresenter ContentSource="SelectedContent"/>
                                </ScrollViewer>
                            </Border>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

    </Grid.Resources>

    <TabControl Name="tabControl" TabStripPlacement="Left">
        <!-- First tab item -->
        <TabItem IsSelected="True">
            <TabItem.Header>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="Profile"/>
                </StackPanel>
            </TabItem.Header>
            <TextBlock Text="Page 1 Sample Text with no foreground set." FontSize="30"/>
        </TabItem>

        <!-- Second tab item -->
        <TabItem IsSelected="True">
            <TabItem.Header>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="Profile"/>
                </StackPanel>
            </TabItem.Header>
            <TextBlock Text="Page 2 Sample Text with foreground set manually." FontSize="30" Foreground="Red"/>
        </TabItem>
    </TabControl>
</Grid>

Ответы [ 4 ]

12 голосов
/ 21 апреля 2011

Я только что столкнулся с той же самой проблемой, и, немного поиграв с ней, думаю, я нашел более элегантное решение.

Я говорю более элегантно, поскольку оно оставит ContentPresenter без изменений.и примените сеттеры переднего плана и веса шрифта к TextElement ContentPresenter (который является в основном присоединенным свойством, но это не относится к делу).

Основное преимущество этого подхода состоит в том, что замена ContentPresenter на TextBlock неявно предполагает, чтозаголовок будет содержать только текст, который ограничивает удобство использования обходного пути и создает менее надежный код.Оставив ContentPresenter на месте, вы разрешите любой контент, например, изображения + текст.

Еще одна вещь, которую вам нужно сделать, это назвать свой ContentPresenter:

<Setter Property="Template">
     <Setter.Value>
         <ControlTemplate TargetType="{x:Type TabItem}">
             <Grid>
                <Border Name="Border" Padding="5,2">
                   <ContentPresenter x:Name="CP" ContentSource="Header"/>
                </Border>
             </Grid>
             <ControlTemplate.Triggers>
                <MultiTrigger>
                   <MultiTrigger.Conditions>
                      <Condition Property="Border.IsMouseOver" Value="True"/>
                      <Condition Property="IsSelected" Value="False"/>
                   </MultiTrigger.Conditions>
                     <Setter Property="TextElement.FontWeight" TargetName="CP" Value="Bold"/>
                     <Setter Property="TextElement.Foreground" TargetName="CP" Value="Black"/>                                
                </MultiTrigger>...

Теперь Foreground и FontWeight не будутнаследуется содержимым TabItem (проверено).

Наслаждайтесь:)

3 голосов
/ 30 августа 2011

К сожалению, если вы установите Foreground (или FontWeight) для ContentPresenter с помощью какого-либо триггера, вы по-прежнему предполагаете, что заголовок будет содержать только текст.

Если вы установите Header = "SomeHeaderName" (т.е. только текст), ContentPresenter сгенерирует TextBlock для размещения этого заголовочного текста; ContentPresenter будет (логическим) родителем этого TextBlock, и поэтому новый Foreground, установленный в ContentPresenter, будет наследоваться этим TextBlock. Это работает нормально.

Однако если заголовку назначен какой-то фрагмент визуального дерева, например, горизонтальная панель StackPanel с изображением и текстовым блоком (или даже одним текстовым блоком), то логическим родителем StackPanel является TabItem, а не ContentPresenter. Наследование работает через логическое дерево, поэтому TextBlock внутри StackPanel в конечном итоге снова унаследует свой Foreground от TabItem; передний план, заданный в ContentPresenter, не влияет на это.

Одно из возможных решений: DataTemplate в конечном итоге применяется к ContentPresenter, поэтому TemplatedParent для корня DataTemplate является ContentPresenter; и наследование работает через барьер TemplatedParent-Child. Так что если вы можете установить TabItem.HeaderTemplate вместо TabItem.Header, тогда вы можете установить Foreground для ContentPresenter заголовка, потому что корень HeaderTemplate будет наследовать Foreground от ContentPresenter. SelectedContent, однако, не будет, потому что Foreground не установлен на TabItem (и содержимое наследует свой Foreground от TabItem).

Надеюсь, это поможет!

3 голосов
/ 09 декабря 2010

Это довольно старое, но я наткнулся на него, когда искал ответ на похожую проблему, и я нашел, что поставленные ответы не очень полезны. Вот как я это исправил.

Если вы измените ContentPresenter на TextBlock в шаблоне элемента управления вашего tabitem, например:

....stuff above here...
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
   <Border Name="Border" Padding="5,2">
        <TextBlock x:Name="TabItemContent" Text="{TemplateBinding Header}"/>
   </Border>
</Grid>
... stuff below here....

Затем в своем триггере на этом шаблоне управления вы указываете имя цели в триггере IsSelected..ie.

...stuff above here...
 <Trigger Property="IsSelected" Value="True">
     <Setter Property="Foreground" TargetName="TabItemContent" Value="Green"/>
     <Setter Property="FontWeight" Value="Bold"/>
</Trigger>
... stuff below here ...

Это должно дать вам зеленый текст, когда вкладка выбрана, а не зеленый все остальное время, при этом оставляя окраску текста в оставшейся части приложения.

0 голосов
/ 21 июня 2010

Каждый элемент управления в wpf наследует свойства от своего родителя.Поскольку цвет TabItem был черным, его дочерний элемент textblock также был черного цвета.Теперь, когда вы изменили цвет переднего плана всего TabItem на зеленый, все его дочерние элементы будут наследовать его.

Здесь вы можете установить передний план вашего TabItem.Header или его содержимого на зеленый, чтобы он не влиял на другиесодержимое в TabItem.Иначе вы можете перевернуть решение.

Иначе Попробуйте это:

<Window.Resources>
    <DataTemplate x:Key="greenHeaderTemplate">
        <StackPanel Orientation="Horizontal"> 
            <TextBlock Text="Profile" 
                       FontWeight="Bold" 
                       Foreground="Green"/> 
        </StackPanel> 
    </DataTemplate>
    <DataTemplate x:Key="defaultHeaderTemplate">
        <StackPanel Orientation="Horizontal"> 
            <TextBlock Text="Profile"/> 
        </StackPanel> 
    </DataTemplate>
</Window.Resources>

<Trigger Property="IsSelected" Value="True">      
    <Setter Property="HeaderTemplate" 
            Value="{StaticResource greenHeaderTemplate}"/> 
</Trigger>

<TabItem IsSelected="True" HeaderTemplate="{StaticResource defaultHeaderTemplate}"> 
    <TextBlock Text="Page 1 Sample Text with no foreground set." FontSize="30"/> 
</TabItem>
...