Почему фон кнопки меняется? - PullRequest
4 голосов
/ 20 августа 2009

Я новичок в WPF и даже не знаю, где искать ответ на этот вопрос. Этот XAML кажется мне очень простым:

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Grid>
    <Button>
      <Button.Style>
        <Style TargetType="{x:Type Button}">
        <Style.Triggers>
          <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Background" Value="Green"/>
          </Trigger>      
        </Style.Triggers>
        </Style>
      </Button.Style>
      <Button.Content>Test</Button.Content>
    </Button>
  </Grid>
</Page>

При наведении курсора на кнопку IsMouseOver меняется на True, и триггер делает фон зеленым. На мгновение. Тогда это становится синим.

Еще лучше: если я присоединяю тот же установщик к свойству IsFocused, то после фокусировки на кнопке цвет фона меняется между зеленым и синим.

Что-то где-то в кнопке (я предполагаю, что это какая-то тема по умолчанию, используемая в Vista), которая заставляет ее так себя вести. Я подозреваю, что есть еще одно свойство, которое должен установить триггер. Но что?

Ответы [ 2 ]

22 голосов
/ 20 августа 2009

Вам нужно изменить Button Template вместо Style. В шаблон встроено что-то под названием ButtonChrome , и именно это вызывает эффект раздражающего синего фокуса. Вот очень простой пересчет элемента управления Button, взятый из предоставленных Простых стилей:

<Style TargetType="{x:Type Button}">
   <Setter Property="SnapsToDevicePixels" Value="true"/>
   <Setter Property="OverridesDefaultStyle" Value="true"/>
   <Setter Property="MinHeight" Value="23"/>
   <Setter Property="MinWidth" Value="75"/>
   <Setter Property="Template">
     <Setter.Value>
       <ControlTemplate TargetType="{x:Type Button}">
         <Border 
           x:Name="Border"  
           CornerRadius="2" 
           BorderThickness="1"
           Background="#C0C0C0"
           BorderBrush="#404040">
           <ContentPresenter 
             Margin="2"
             HorizontalAlignment="Center"
             VerticalAlignment="Center"
             RecognizesAccessKey="True"/>
         </Border>
         <ControlTemplate.Triggers>
           <Trigger Property="IsKeyboardFocused" Value="true">
             <Setter TargetName="Border" Property="BorderBrush" Value="#202020" />
           </Trigger>
           <Trigger Property="IsDefaulted" Value="true">
             <Setter TargetName="Border" Property="BorderBrush" Value="#202020" />
           </Trigger>
           <Trigger Property="IsMouseOver" Value="true">
             <Setter TargetName="Border" Property="Background" Value="#808080" />
           </Trigger>
           <Trigger Property="IsPressed" Value="true">
             <Setter TargetName="Border" Property="Background" Value="#E0E0E0" />
             <Setter TargetName="Border" Property="BorderBrush" Value="#606060" />
           </Trigger>
           <Trigger Property="IsEnabled" Value="false">
             <Setter TargetName="Border" Property="Background" Value="#EEEEEE" />
             <Setter TargetName="Border" Property="BorderBrush" Value="#AAAAAA" />
             <Setter Property="Foreground" Value="#888888"/>
           </Trigger>
         </ControlTemplate.Triggers>
       </ControlTemplate>
     </Setter.Value>
   </Setter>
 </Style>

Вы можете видеть, что, повторно шаблонируя элемент управления, вы можете изменить его визуальное дерево . Визуальное дерево в этом шаблоне - это не что иное, как Border, которое содержит ContentPresenter (чтобы вы могли видеть содержимое кнопки). Таким образом, я эффективно удалил ButtonChrome из визуального дерева.

6 голосов
/ 20 августа 2009

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

Причина, по которой он на мгновение был зеленым, а затем синим, заключается в том, что тема по умолчанию ControlTemplate для Button уже имела IsMouseOver Trigger для изменения фона.

Затем вы добавили еще один в свой Style. Это не заменяет существующее, потому что вы можете иметь несколько Trigger с одним и тем же свойством и значением, которые имеют очень разные Setter с и делают совершенно разные вещи.

Так что он пытался сделать оба, и сначала сделал зеленый.

...