Подтвердить что ты не робот

Установка цвета TabItem foreground также устанавливает цвет переднего плана TabControl

У меня есть 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>
4b9b3361

Ответ 1

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

Я говорю более элегантно, так как он оставил бы 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 (проверено).

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

Ответ 2

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

Если вы измените 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.

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

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

Ответ 3

К сожалению, если вы устанавливаете 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. Выбранный элемент, однако, не будет, потому что Foreground не установлен в TabItem (и содержимое наследует его Foreground от TabItem).

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

Ответ 4

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

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

Else Попробуйте следующее:

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