¿Cómo se cambia el fondo de un botón al pasar el mouse en WPF?

Resuelto Sepehr Mohammadi asked hace 11 años • 6 respuestas

Tengo un botón en mi página con este XAML:

<Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Bottom" 
    Width="50" Height="50" HorizontalContentAlignment="Left" 
    BorderBrush="{x:Null}" Foreground="{x:Null}" Margin="50,0,0,0">
    <Button.Style>
        <Style TargetType="Button">
            <Setter Property="Background" Value="Green"/>
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Background" Value="Red"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>

Pero cuando coloco el mouse sobre mi botón, el fondo del botón cambia al fondo gris predeterminado de Windows.
¿Cuál es el problema?

Esta es la imagen del botón antes y después de pasar el mouse:
Antes:
Antes
Después:
Después

Sepehr Mohammadi avatar Jun 23 '13 16:06 Sepehr Mohammadi
Aceptado

Para eliminar el MouseOvercomportamiento predeterminado en el, Buttondeberá modificar el archivo ControlTemplate. Cambiar su Styledefinición a la siguiente debería funcionar:

<Style TargetType="{x:Type Button}">
    <Setter Property="Background" Value="Green"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border Background="{TemplateBinding Background}" BorderBrush="Black" BorderThickness="1">
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Background" Value="Red"/>
        </Trigger>
    </Style.Triggers>
</Style>

EDITAR: Es un retraso de algunos años, pero en realidad puedes configurar el pincel de borde dentro del borde que está allí. No sé si se señaló eso pero no parece que fuera así...

Richard E avatar Jun 23 '2013 10:06 Richard E

Todas las respuestas hasta ahora implican reemplazar completamente el comportamiento predeterminado del botón por algo más. Sin embargo, en mi humilde opinión, es útil e importante comprender que es posible cambiar solo la parte que le interesa editando la plantilla predeterminada existente para un elemento XAML.

En el caso de tratar con el efecto de desplazamiento en un botón de WPF, el cambio en la apariencia de un Buttonelemento de WPF se debe a un Triggerestilo predeterminado para Button, que se basa en la IsMouseOverpropiedad y establece las propiedades Backgroundy BorderBrushdel Borderelemento de nivel superior. en la plantilla de control. El Buttonfondo del elemento está debajo del Borderfondo del elemento, por lo que cambiar la Button.Backgroundpropiedad no impide que se vea el efecto de desplazamiento.

Con un poco de esfuerzo, podría anular este comportamiento con su propio configurador, pero debido a que el elemento que necesita afectar está en la plantilla y no es accesible directamente en su propio XAML, ese enfoque sería difícil y, en mi humilde opinión, demasiado complejo.

Otra opción sería utilizar el gráfico como para Contenten Buttonlugar de Background. Si necesita contenido adicional además del gráfico, puede combinarlo con a Gridcomo objeto de nivel superior en el contenido.

Sin embargo, si literalmente solo desea deshabilitar el efecto de desplazamiento por completo (en lugar de simplemente ocultarlo), puede usar Visual Studio XAML Designer:

  1. Mientras edita su XAML, seleccione la pestaña "Diseño" .
  2. En la pestaña "Diseño" , busque el botón cuyo efecto desea desactivar.
  3. Haga clic derecho en ese botón y elija "Editar plantilla/Editar una copia..." . Seleccione en el mensaje dónde desea que se coloque el nuevo recurso de plantilla. Parecerá que esto no hace nada, pero de hecho el Diseñador habrá agregado nuevos recursos donde usted lo indicó y habrá cambiado el elemento del botón para hacer referencia al estilo que usa esos recursos como plantilla del botón.
  4. Ahora puedes ir a editar ese estilo. Lo más fácil es eliminar o comentar (por ejemplo, Ctrl+ E, C) el <Trigger Property="IsMouseOver" Value="true">...</Trigger>elemento. Por supuesto, puedes realizar cualquier cambio en la plantilla que desees en ese momento.

Cuando haya terminado, el estilo del botón se verá así:

<p:Style x:Key="FocusVisual">
  <Setter Property="Control.Template">
    <Setter.Value>
      <ControlTemplate>
        <Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</p:Style>
<SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
<SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
<SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD"/>
<SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/>
<SolidColorBrush x:Key="Button.Pressed.Background" Color="#FFC4E5F6"/>
<SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/>
<SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/>
<SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/>
<SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/>
<p:Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
  <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
  <Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
  <Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
  <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
  <Setter Property="BorderThickness" Value="1"/>
  <Setter Property="HorizontalContentAlignment" Value="Center"/>
  <Setter Property="VerticalContentAlignment" Value="Center"/>
  <Setter Property="Padding" Value="1"/>
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type Button}">
        <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
          <ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
        </Border>
        <ControlTemplate.Triggers>
          <Trigger Property="IsDefaulted" Value="true">
            <Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
          </Trigger>
          <!--<Trigger Property="IsMouseOver" Value="true">
            <Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background}"/>
            <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/>
          </Trigger>-->
          <Trigger Property="IsPressed" Value="true">
            <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/>
            <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/>
          </Trigger>
          <Trigger Property="IsEnabled" Value="false">
            <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/>
            <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/>
            <Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
          </Trigger>
        </ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</p:Style>

(Nota: puede omitir las p:calificaciones del espacio de nombres XML en el código real... Las proporciono aquí solo porque el formateador de código XML de Stack Overflow se confunde con <Style/>elementos que no tienen un nombre completo con el espacio de nombres XML).

Si desea aplicar el mismo estilo a otros botones, puede simplemente hacer clic derecho en ellos y elegir "Editar plantilla/Aplicar recurso" y seleccionar el estilo que acaba de agregar para el primer botón. Incluso puedes hacer que ese estilo sea el estilo predeterminado para todos los botones, usando las técnicas normales para aplicar un estilo predeterminado a elementos en XAML.

Peter Duniho avatar Sep 05 '2017 21:09 Peter Duniho

Esto funcionó bien para mí.

Estilo de botón

<Style x:Key="TransparentStyle" TargetType="{x:Type Button}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Border>
                    <Border.Style>
                        <Style TargetType="{x:Type Border}">
                            <Style.Triggers>
                                <Trigger Property="IsMouseOver" Value="True">
                                    <Setter Property="Background" Value="DarkGoldenrod"/>
                                </Trigger>
                            </Style.Triggers>
                        </Style>
                    </Border.Style>
                    <Grid Background="Transparent">
                        <ContentPresenter></ContentPresenter>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Botón

<Button Style="{StaticResource TransparentStyle}" VerticalAlignment="Top" HorizontalAlignment="Right" Width="25" Height="25"
        Command="{Binding CloseWindow}">
    <Button.Content >
        <Grid Margin="0 0 0 0">
            <Path Data="M0,7 L10,17 M0,17 L10,7" Stroke="Blue" StrokeThickness="2" HorizontalAlignment="Center" Stretch="None" />
        </Grid>
    </Button.Content>
</Button>

Notas

  • El botón muestra una pequeña cruz azul, muy parecida a la que se usa para cerrar una ventana.
  • Al configurar el fondo de la cuadrícula en "Transparente", agrega un hittest, lo que significa que si el mouse está en cualquier lugar sobre el botón, funcionará. Omita esta etiqueta y el botón solo se iluminará si el mouse está sobre una de las líneas vectoriales en el ícono (esto no es muy útil).
Contango avatar Mar 23 '2016 17:03 Contango