¿Cómo eliminar el efecto predeterminado del mouse sobre los botones WPF?

85

Mi problema es que en WPF, cada vez que intento cambiar el color del fondo de un botón usando activadores o animaciones, el efecto de mouse over predeterminado (de ser gris con ese brillo naranja) parece tener prioridad.

Después de extensas búsquedas, no tengo ni idea de cómo eliminar este efecto.

Nellius
fuente

Respuestas:

17

Debe crear su propia plantilla de botones personalizados para tener un control total sobre la apariencia en todos los estados. Aquí tienes un tutorial .

Mark Heath
fuente
2
Gracias, estuvo perfecto. Fue más complicado de hacer de lo que pensé que sería, pero ahora todo funciona bien.
Nellius
18
Por alguna razón, hay 100 respuestas sobre la creación de plantillas personalizadas para los controles WPF, y todas son innecesariamente incorrectas. No hay razón para tener problemas para escribir 50 líneas de código de plantilla para un botón para cambiar 1 cosa. Todo lo que tienes que hacer es en el diseñador xaml, hacer clic derecho en el control y crear una copia del código de la plantilla. VS creará un estilo a partir de ese botón exacto y puedes modificarlo desde allí. Toma literalmente 2 segundos.
The Muffin Man
@TheMuffinMan Fantástico, pero ¿le parece un poco extraño que se necesiten 50 líneas de código de plantilla para evitar que un botón cambie el color de fondo al pasar el mouse? Qué marco tan estúpidamente complicado es WPF.
Ash
@Ash O se podría argumentar que está guiando al usuario en la dirección en la que debería ir. Si tiene un botón que requiere un nuevo estado de desplazamiento, probablemente sea un nuevo TIPO de botón; tal vez un botón de navegación, un botón de bandeja, etc. Si es así, no debería modificar propiedades únicas para él, debería tener su propio control o grupo de estilos. Y eso es lo que esto te hace hacer.
Matt Kenefick
108

Esto es similar a la solución a la que se refiere Mark Heath, pero no tiene tanto código para crear un botón muy básico, sin el efecto de animación del mouse incorporado. Conserva un simple efecto de pasar el ratón por encima de mostrar el borde del botón en negro.

El estilo se puede insertar en la sección Window.Resources o UserControl.Resources, por ejemplo (como se muestra).

<UserControl.Resources>
    <!-- This style is used for buttons, to remove the WPF default 'animated' mouse over effect -->
    <Style x:Key="MyButtonStyle" TargetType="Button">
        <Setter Property="OverridesDefaultStyle" Value="True"/>
        <Setter Property="Margin" Value="5"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Border Name="border" 
                        BorderThickness="1"
                        Padding="4,2" 
                        BorderBrush="DarkGray" 
                        CornerRadius="3" 
                        Background="{TemplateBinding Background}">
                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="border" Property="BorderBrush" Value="Black" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>

<!-- usage in xaml -->
<Button Style="{StaticResource MyButtonStyle}">Hello!</Button>
dodgy_coder
fuente
2
Me gusta mucho esa solución. Sin embargo, el mouse sobre los disparadores se activa solo cuando el mouse está sobre el texto del botón. Agregué un bloque de texto con un ancho específico dentro del botón para solucionar ese problema.
Dave
Usted señor es un santo.
krobelusmeetsyndra
25

Solo para agregar una solución muy simple, eso fue lo suficientemente bueno para mí, y creo que aborda el problema del OP. Usé la solución en esta respuesta, excepto con un Backgroundvalor regular en lugar de una imagen.

<Style x:Key="SomeButtonStyle" TargetType="Button">
    <Setter Property="Background" Value="Transparent" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Grid Background="{TemplateBinding Background}">
                    <ContentPresenter />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

No hay que volver Backgrounda crear plantillas más allá de forzar a que siempre sea el Transparentfondo del botón de la plantilla; el mouseover ya no afecta el fondo una vez hecho esto. Obviamente reemplácelo Transparentcon cualquier valor preferido.

Lyall
fuente
10

El Muffin Man tenía una respuesta muy simple que funcionó para mí.

Para agregar una dirección un poco más específica, al menos para VS 2013:

  • Haga clic derecho en el control
  • Seleccione Editar plantilla => Editar una copia ...
  • Seleccioné 'Aplicación' para saber dónde guardar el estilo
    • Desde aquí puede editar directamente App.xaml y ver las propiedades con nombre intuitivo. Para mis propósitos, acabo de configurar RenderMouseOver = "False"
  • Luego, en MainWindow.xaml o donde sea que esté su GUI, puede pegar el nuevo estilo al final de la etiqueta Button, por ejemplo ... Style="{DynamicResource MouseOverNonDefault}"/>
Benji-Man
fuente
¿Quién es el hombre muffin?
Mike W
LOL. Hizo la segunda respuesta a la pregunta-respuesta aceptada por el propietario. No estaba seguro si estaba preguntando en serio o bromeando. Difícil de decir con un nombre como Muffin Man.
Benji-Man
5

Este enlace me ayudó mucho http://www.codescratcher.com/wpf/remove-default-mouse-over-effect-on-wpf-buttons/

Defina un estilo en UserControl.Resources o Window.Resources

 <Window.Resources>
        <Style x:Key="MyButton" TargetType="Button">
            <Setter Property="OverridesDefaultStyle" Value="True" />
            <Setter Property="Cursor" Value="Hand" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Border Name="border" BorderThickness="0" BorderBrush="Black" Background="{TemplateBinding Background}">
                            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Opacity" Value="0.8" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>

Luego agregue el estilo a su botón de esta manera Style = "{StaticResource MyButton}"

<Button Name="btnSecond" Width="350" Height="120" Margin="15" Style="{StaticResource MyButton}">
    <Button.Background>
        <ImageBrush ImageSource="/Remove_Default_Button_Effect;component/Images/WithStyle.jpg"></ImageBrush>
    </Button.Background>
</Button>
Arash.Zandi
fuente
4

Si alguien no quiere anular la plantilla de control predeterminada, aquí está la solución.

Puede crear DataTemplate para el botón que puede tener TextBlock y luego puede escribir el activador de propiedad en la propiedad IsMouseOver para deshabilitar el efecto del mouse sobre el. La altura de TextBlock y Button debe ser la misma.

<Button Background="Black" Margin="0" Padding="0" BorderThickness="0" Cursor="Hand" Height="20">
    <Button.ContentTemplate>
        <DataTemplate>
            <TextBlock Text="GO" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" TextDecorations="Underline" Margin="0" Padding="0" Height="20">
                <TextBlock.Style>
                    <Style TargetType="TextBlock">
                        <Style.Triggers>
                            <Trigger Property ="IsMouseOver" Value="True">
                                <Setter Property= "Background" Value="Black"/>
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </TextBlock.Style>
            </TextBlock>
        </DataTemplate>
    </Button.ContentTemplate>
</Button>
Prateek Rai
fuente
1

Una extensión en la respuesta de dodgy_coder que agrega soporte para ..

  • Mantener el estilo del botón WPF
  • Agrega soporte para IsSelected y hover, es decir, un botón conmutado

        <Style x:Key="Button.Hoverless" TargetType="{x:Type ButtonBase}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ButtonBase}">
                        <Border Name="border"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                Padding="{TemplateBinding Padding}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                Background="{TemplateBinding Background}">
                            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
                        </Border>
                        <ControlTemplate.Triggers>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="IsMouseOver" Value="True" />
                                    <Condition Property="Selector.IsSelected" Value="False" />
                                </MultiTrigger.Conditions>
                                <Setter Property="Background" Value="#FFBEE6FD" />
                            </MultiTrigger>
    
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="IsMouseOver" Value="True" />
                                    <Condition Property="Selector.IsSelected" Value="True" />
                                </MultiTrigger.Conditions>
                                <Setter Property="Background" Value="#BB90EE90" />
                            </MultiTrigger>
    
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="IsMouseOver" Value="False" />
                                    <Condition Property="Selector.IsSelected" Value="True" />
                                </MultiTrigger.Conditions>
                                <Setter Property="Background" Value="LightGreen" />
                            </MultiTrigger>
    
                            <Trigger Property="IsPressed" Value="True">
                                <Setter TargetName="border" Property="Opacity" Value="0.95" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    

ejemplos ..

<Button Content="Wipe On" Selector.IsSelected="True" /> <Button Content="Wipe Off" Selector.IsSelected="False" />

Stoj
fuente
0

Usando un activador de plantilla:

<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
    <Setter Property="Background" Value="White"></Setter>
    ...
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border Background="{TemplateBinding Background}">
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="White"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
Laine Mikael
fuente