¿Cómo se cambia el fondo de un botón al pasar el mouse en WPF?
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:
Después:
Para eliminar el MouseOver
comportamiento predeterminado en el, Button
deberá modificar el archivo ControlTemplate
. Cambiar su Style
definició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í...
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 Button
elemento de WPF se debe a un Trigger
estilo predeterminado para Button
, que se basa en la IsMouseOver
propiedad y establece las propiedades Background
y BorderBrush
del Border
elemento de nivel superior. en la plantilla de control. El Button
fondo del elemento está debajo del Border
fondo del elemento, por lo que cambiar la Button.Background
propiedad 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 Content
en Button
lugar de Background
. Si necesita contenido adicional además del gráfico, puede combinarlo con a Grid
como 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:
- Mientras edita su XAML, seleccione la pestaña "Diseño" .
- En la pestaña "Diseño" , busque el botón cuyo efecto desea desactivar.
- 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.
- 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.
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).