TabItem BorderBrush не обновляется при запуске IsMouseOver

У меня есть MultiDataTrigger, где, если свойство в моей модели представления истинно И IsMouseOver на TabItem истинно, тогда граница должна отображаться красной с толщиной 2,5.

Мне не удалось заставить работать и свойство, и IsMouseOver, поэтому я попробовал только свое свойство. Это работало правильно, но все еще имело ожидаемую проблему, когда он был красным с толщиной 2,5, пока я не навел курсор на вкладку. Затем я попытался удалить свойство модели представления и просто использовал проверку IsMouseOver в качестве условия. Это не работает. Ниже приведен код только с IsMouseOver.

<TabItem x:Name="TabItemNotWorking" Header="NotWorking">
            <TabItem.Style>
                <Style TargetType="TabItem">
                    <Style.Triggers>
                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding IsMouseOver RelativeSource={RelativeSource Self}}" Value="true" />
                                <!--<Condition Binding="{Binding Counter, Converter={StaticResource IntIsGreaterThanZeroToBool}}" Value="true" />-->
                            </MultiDataTrigger.Conditions>
                                <Setter Property="TabItem.BorderBrush" Value="Red"/>
                                <Setter Property="TabItem.BorderThickness" Value="2.5"/>
                        </MultiDataTrigger>
                    </Style.Triggers>
                </Style>
            </TabItem.Style>    
            <!--Content in here-->
</TabItem>

Я исправил это, воспользовавшись советом Майка Стробеля перезаписать шаблон TabItem. Теперь моя красная рамка будет отображаться всякий раз, когда мое свойство ViewModel имеет значение true, независимо от того, наведен ли указатель мыши на TabItem. Вот мое решение (я добавляю комментарии к измененным участкам кода):

<LinearGradientBrush x:Key="TabItemHotBackground"
                     StartPoint="0,0"
                     EndPoint="0,1">
        <LinearGradientBrush.GradientStops>
            <GradientStop Color="#EAF6FD"
                      Offset="0.15"/>
            <GradientStop Color="#D9F0FC"
                      Offset=".5"/>
            <GradientStop Color="#BEE6FD"
                      Offset=".5"/>
            <GradientStop Color="#A7D9F5"
                      Offset="1"/>
        </LinearGradientBrush.GradientStops>
    </LinearGradientBrush>
    <SolidColorBrush x:Key="TabItemSelectedBackground"
                 Color="#F9F9F9"/>
    <SolidColorBrush x:Key="TabItemDisabledBackground"
                 Color="#F4F4F4"/>
    <SolidColorBrush x:Key="TabItemHotBorderBrush"
                 Color="#3C7FB1"/>
    <SolidColorBrush x:Key="TabItemDisabledBorderBrush"
                 Color="#FFC9C7BA"/>
    <Style TargetType="{x:Type TabItem}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TabItem}">
                    <Grid SnapsToDevicePixels="true">
                        <Border Name="Bd"
                            Padding="{TemplateBinding Padding}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            Background="{TemplateBinding Background}"
                            BorderThickness="1,1,1,0">
                            <ContentPresenter Name="Content"
                                          ContentSource="Header"
                                          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                          HorizontalAlignment="{Binding Path=HorizontalContentAlignment,RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
                                          VerticalAlignment="{Binding Path=VerticalContentAlignment,RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
                                          RecognizesAccessKey="True"/>
                        </Border>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="true">
                            <Setter TargetName="Bd" Property="Background" Value="{StaticResource TabItemHotBackground}"/>
                        </Trigger>
                        <Trigger Property="IsSelected" Value="true">
                            <Setter Property="Panel.ZIndex" Value="1"/>
                            <Setter TargetName="Bd" Property="Background" Value="{StaticResource TabItemSelectedBackground}"/>
                        </Trigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsSelected" Value="false"/>
                                <Condition Property="IsMouseOver" Value="true"/>
                            </MultiTrigger.Conditions>
                            <Setter TargetName="Bd" Property="BorderBrush" Value="{StaticResource TabItemHotBorderBrush}"/>
                        </MultiTrigger> 

                        <!--HERE ARE THE START OF MY CHANGES-->
                        <DataTrigger Binding="{Binding Counter, Converter={StaticResource IntIsGreaterThanZeroToBool}}" Value="true">
                            <Setter TargetName="Bd" Property="BorderBrush" Value="Red"/>
                            <Setter TargetName="Bd" Property="BorderThickness" Value="2.5"/>
                        </DataTrigger>
                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type TabItem}}}"  Value="true" />
                                <Condition Binding="{Binding Counter, Converter={StaticResource IntIsGreaterThanZeroToBool}}" Value="true" />
                            </MultiDataTrigger.Conditions>
                            <Setter TargetName="Bd" Property="BorderBrush" Value="Red"/>
                            <Setter TargetName="Bd" Property="BorderThickness" Value="2.5"/>
                        </MultiDataTrigger>
                        <!--HERE ARE THE END OF MY CHANGES-->

                        <Trigger Property="TabStripPlacement" Value="Bottom">
                            <Setter TargetName="Bd" Property="BorderThickness" Value="1,0,1,1"/>
                        </Trigger>
                        <Trigger Property="TabStripPlacement" Value="Left">
                            <Setter TargetName="Bd" Property="BorderThickness" Value="1,1,0,1"/>
                        </Trigger>
                        <Trigger Property="TabStripPlacement" Value="Right">
                            <Setter TargetName="Bd" Property="BorderThickness" 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 TargetName="Content" Property="Margin" 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 TargetName="Content" Property="Margin" 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 TargetName="Content" Property="Margin" 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 TargetName="Content" Property="Margin" Value="1,0,0,0"/>
                        </MultiTrigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter TargetName="Bd" Property="Background" Value="{StaticResource TabItemDisabledBackground}"/>
                            <Setter TargetName="Bd" Property="BorderBrush" Value="{StaticResource TabItemDisabledBorderBrush}"/>
                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

person jsirr13    schedule 12.11.2014    source источник
comment
Похоже, это связано с WPF. Это правильно? Если да, добавьте тег WPF.   -  person sfuqua    schedule 12.11.2014
comment
Условие IsMouseOver, о котором вы упоминали в последний раз, работает для меня, хотя со стилем Aero по умолчанию в Windows 7 кажется, что красный BorderBrush применяется только тогда, когда вкладка фактически выбрана.; граница при наведении становится голубоватой, когда вкладка не выбрана. Возможно, вам придется изменить шаблон по умолчанию, чтобы получить желаемые результаты.   -  person Mike Strobel    schedule 12.11.2014
comment
У вас есть фон для вашего TabItem (даже прозрачный)? Я видел аналогичную проблему с сеткой, потому что по умолчанию свойство background имеет значение null и не будет использоваться для проверки попадания.   -  person Chris    schedule 12.11.2014
comment
Нет, у меня нет других свойств, установленных для TabItem, кроме его содержимого и заголовка. Установка свойства background, похоже, не помогла. Это почти похоже на то, когда я наводил курсор на TabItem, он использует совершенно другой стиль. Поскольку установка свойства фона работала только в том случае, если вкладка НЕ ​​была выбрана и мышь НЕ находилась над вкладкой.   -  person jsirr13    schedule 12.11.2014


Ответы (1)


Вы заметите, что следующее условие работает, но только когда выбрана вкладка:

<Condition Binding="{Binding IsMouseOver RelativeSource={RelativeSource Self}}"
           Value="true" />

И вот почему: обратите внимание на этот отрывок из стандартного шаблона TabItem для темы Aero.

<MultiTrigger>
  <MultiTrigger.Conditions>
    <Condition Property="IsSelected"
               Value="false"/>
    <Condition Property="IsMouseOver"
               Value="true"/>
  </MultiTrigger.Conditions>
  <Setter TargetName="Bd"
          Property="BorderBrush"
          Value="{StaticResource TabItemHotBorderBrush}"/>
</MultiTrigger>

Стиль переопределяет BorderBrush при наведении курсора мыши, когда вкладка не выбрана, поэтому в этом случае кисть границы применяться не будет.

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

person Mike Strobel    schedule 12.11.2014
comment
У вас есть ссылка на шаблон TabItem по умолчанию? Я нашел один, но он не имеет тех же условий срабатывания, что и тот, который вы опубликовали. Спасибо! - person jsirr13; 12.11.2014
comment
Он поставляется с Blend в папке SystemThemes. Если у вас его нет, я скопировал содержимое в эту суть. Обратите внимание, что файл содержит стили Aero для всех элементов управления. Вам придется просмотреть их, чтобы найти подходящие. - person Mike Strobel; 12.11.2014