Come rimuovere l'effetto di passaggio del mouse predefinito sui pulsanti WPF?


87

Il mio problema è che in WPF, ogni volta che provo a cambiare il colore dello sfondo di un pulsante utilizzando trigger o animazioni, l'effetto mouseover predefinito (di essere grigio con quel bagliore arancione) sembra avere la priorità.

Dopo lunghe ricerche non ho idea di come rimuovere questo effetto.

Risposte:


17

È necessario creare il proprio modello di pulsante personalizzato per avere il pieno controllo sull'aspetto in tutti gli stati. Ecco un tutorial .


2
Grazie, è stato perfetto. È stato più complicato di quanto pensassi, ma ora funziona tutto bene.
Nellius

19
Per qualche motivo ci sono 100 risposte sulla creazione di modelli personalizzati per i controlli WPF e sono tutte inutilmente sbagliate. Non c'è motivo di lottare per scrivere 50 righe di codice modello per un pulsante al fine di cambiare 1 cosa. Tutto quello che devi fare è nel designer xaml fare clic con il pulsante destro del mouse sul controllo e creare una copia del codice del modello. VS creerà uno stile da quel pulsante esatto e potrai modificarlo da lì. Prende letteralmente 2 secondi.
The Muffin Man

@TheMuffinMan Fantastico, ma trovi anche un po 'strano che siano necessarie 50 righe di codice modello per impedire a un pulsante di cambiare il colore di sfondo al passaggio del mouse? Che quadro stupidamente complicato è WPF.
Ash,

@Ash Oppure si potrebbe sostenere che sta guidando l'utente nella direzione in cui dovrebbe andare. Se hai un pulsante che richiede un nuovo stato al passaggio del mouse, è probabile che sia un nuovo TIPO di pulsante; forse un pulsante di navigazione, un pulsante nella barra delle applicazioni, ecc. In tal caso, non dovresti modificare le proprietà una tantum, dovrebbe avere il proprio controllo o gruppo di stili. E questo è più o meno quello che ti fa fare.
Matt Kenefick

@TheMuffinMan: sei veramente l' uomo! 10 anni di lavoro con WPF e ho appena scoperto l'opzione "Modifica modello"!
Paul,

109

Questo è simile alla soluzione indicata da Mark Heath ma con non tanto codice per creare solo un pulsante molto semplice, senza l'effetto di animazione del mouse incorporato. Conserva un semplice effetto di passaggio del mouse mostrando il bordo del pulsante in nero.

Lo stile può essere inserito nella sezione Window.Resources o UserControl.Resources, ad esempio (come mostrato).

<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>

2
Mi piace molto quella soluzione. Tuttavia, i trigger al passaggio del mouse si attivano solo quando il mouse si trova sul testo del pulsante. Ho aggiunto un blocco di testo con una larghezza specificata all'interno del pulsante per risolvere il problema.
Dave,

Sei un santo, signore.
krobelusmeetsyndra

26

Solo per aggiungere una soluzione molto semplice, per me era abbastanza buono e penso che risolva il problema dell'OP. Ho usato la soluzione in questa risposta tranne che con un Backgroundvalore regolare invece di un'immagine.

<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>

Nessun nuovo modello oltre a costringere Backgrounda essere sempre lo Transparentsfondo dal pulsante modellato: il passaggio del mouse non influisce più sullo sfondo una volta fatto. Ovviamente sostituire Transparentcon qualsiasi valore preferito.


11

The Muffin Man aveva una risposta molto semplice che ha funzionato per me.

Per aggiungere una direzione un po 'più specifica, almeno per VS 2013:

  • Fare clic con il pulsante destro del mouse sul controllo
  • Seleziona Modifica modello => Modifica una copia ...
  • Ho selezionato "Applicazione" per dove salvare lo stile
    • Da qui puoi modificare direttamente App.xaml e vedere le proprietà dal nome intuitivo. Per i miei scopi, ho appena impostato RenderMouseOver = "False"
  • Quindi, nella MainWindow.xaml o ovunque sia la tua GUI, puoi incollare il nuovo stile alla fine del tag Button, ad es. ... Style="{DynamicResource MouseOverNonDefault}"/>

Chi è l'uomo dei muffin?
Mike W

LOL. Ha dato la seconda risposta alla domanda accettata dal proprietario. Non ero sicuro che lo stessi chiedendo seriamente o scherzando. Difficile dirlo con un nome come Muffin Man.
Benji-Man

6

Questo collegamento mi ha aiutato molto http://www.codescratcher.com/wpf/remove-default-mouse-over-effect-on-wpf-buttons/

Definisci uno stile in 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>

Quindi aggiungi lo stile al tuo pulsante in questo modo 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>

4

Se qualcuno non vuole sovrascrivere il modello di controllo predefinito, ecco la soluzione.

Puoi creare DataTemplate per il pulsante che può avere TextBlock e quindi puoi scrivere Property trigger sulla proprietà IsMouseOver per disabilitare l'effetto del passaggio del mouse. L'altezza di TextBlock e Button dovrebbe essere la stessa.

<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>

1

Un'estensione sulla risposta di dodgy_coder che aggiunge il supporto per ..

  • Mantenimento dello stile del pulsante WPF
  • Aggiunge il supporto per IsSelected e hover, ovvero un pulsante attivato / disattivato

        <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>
    

esempi ..

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


0

Utilizzando un trigger di modello:

<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>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.