105 votes

Comment changer l'arrière-plan d'un bouton MouseOver dans WPF ?

J'ai un bouton sur ma page avec ce 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>

Mais lorsque je place la souris sur mon bouton, l'arrière-plan du bouton devient le fond gris par défaut de Windows.
Quel est le problème ?

Voici l'image du bouton avant et après le passage de la souris :
Avant :
Before
Après :
After

194voto

Richard E Points 4619

Pour supprimer l'option par défaut MouseOver comportement sur le Button vous devrez modifier le ControlTemplate . Changer votre Style La définition de ce qui suit devrait faire l'affaire :

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

EDIT : C'est avec quelques années de retard, mais vous pouvez en fait définir la brosse de bordure à l'intérieur de la bordure qui est là. Je ne sais pas si cela a été signalé, mais il ne semble pas que ce soit le cas...

34voto

Peter Duniho Points 21282

Toutes les réponses proposées jusqu'à présent impliquent de remplacer complètement le comportement du bouton par défaut par quelque chose d'autre. Cependant, il est utile et important de comprendre qu'il est possible de modifier le comportement des boutons par défaut. juste la partie qui vous intéresse en modifiant le modèle par défaut existant d'un élément XAML.

Dans le cas du traitement de l'effet de survol d'un bouton WPF, le changement d'apparence dans un WPF Button est causé par un Trigger dans le style par défaut de la Button qui est basé sur le IsMouseOver et définit la propriété Background y BorderBrush des propriétés du niveau supérieur Border dans le modèle de contrôle. Le site Button se trouve sous l'arrière-plan de l'élément Border donc la modification de l'arrière-plan de l'élément Button.Background n'empêche pas de voir l'effet de survol.

Avec un peu d'effort, vous pourriez remplacer ce comportement par votre propre setter, mais comme l'élément que vous devez affecter se trouve dans le modèle et n'est pas directement accessible dans votre propre XAML, cette approche serait difficile et, à mon avis, trop complexe.

Une autre option consisterait à utiliser le graphique comme le Content pour le Button plutôt que le Background . Si vous avez besoin d'un contenu supplémentaire par rapport au graphique, vous pouvez les combiner avec une Grid comme objet de premier niveau dans le contenu.

Toutefois, si vous souhaitez simplement désactiver entièrement l'effet de survol (au lieu de simplement le masquer), vous pouvez utiliser le concepteur XAML de Visual Studio :

  1. Pendant l'édition de votre XAML, sélectionnez l'option "Design" onglet.
  2. Dans le "Design" recherchez le bouton pour lequel vous souhaitez désactiver l'effet.
  3. Cliquez à droite sur ce bouton, et choisissez "Modifier le modèle/Éditer une copie..." . Sélectionnez dans l'invite qui s'affiche l'endroit où vous souhaitez placer la nouvelle ressource de modèle. Cette opération semble ne rien faire, mais en fait, le concepteur aura ajouté de nouvelles ressources à l'endroit que vous lui avez indiqué et modifié votre élément de bouton pour qu'il fasse référence au style qui utilise ces ressources comme modèle de bouton.
  4. Maintenant, vous pouvez aller éditer ce style. Le plus simple est de supprimer ou de commenter (par ex. Ctrl + E , C ) le <Trigger Property="IsMouseOver" Value="true">...</Trigger> élément. Bien entendu, vous pouvez apporter toutes les modifications que vous souhaitez au modèle à ce stade.

Lorsque vous aurez terminé, le style du bouton ressemblera à quelque chose comme ceci :

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

(Note : vous pouvez omettre le p: Les qualifications de l'espace de nom XML dans le code réel Je les fournis ici uniquement parce que le formateur de code XML de Stack Overflow s'embrouille dans les cas suivants <Style/> qui n'ont pas un nom entièrement qualifié avec un espace de noms XML).

Si vous souhaitez appliquer le même style à d'autres boutons, il vous suffit de cliquer avec le bouton droit de la souris sur ces derniers et de choisir "Modifier le modèle/appliquer la ressource" et sélectionnez le style que vous venez d'ajouter pour le premier bouton. Vous pouvez même faire de ce style le style par défaut de tous les boutons, en utilisant les techniques habituelles pour appliquer un style par défaut aux éléments dans XAML.

16voto

Contango Points 7976

Cela a bien fonctionné pour moi.

Style des boutons

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

Bouton

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

Notes

  • Le bouton affiche une petite croix bleue, un peu comme celle utilisée pour fermer une fenêtre.
  • En définissant l'arrière-plan de la grille sur "Transparent", on ajoute un hittest, ce qui signifie que si la souris se trouve n'importe où au-dessus du bouton, celui-ci fonctionnera. Si vous omettez cette balise, le bouton ne s'allumera que si la souris se trouve au-dessus d'une des lignes vectorielles de l'icône (ce qui n'est pas très utilisable).

7voto

Justin Adrias Points 341

Je veux juste partager le style de bouton de mon ResourceDictionary que j'ai utilisé. Vous pouvez modifier librement l'arrière-plan onHover dans les déclencheurs de style. " ColorAnimation vers \= *votre BG souhaité (c'est-à-dire #FFCEF7A0)". Le BG du bouton reviendra aussi automatiquement à son BG original après l'état mouseOver. Vous pouvez même définir la vitesse de la transition.

Dictionnaire des ressources

<Style x:Key="Flat_Button" TargetType="{x:Type Button}">
    <Setter Property="Width" Value="100"/>
    <Setter Property="Height" Value="50"/>
    <Setter Property="Margin" Value="2"/>
    <Setter Property="FontFamily" Value="Arial Narrow"/>
    <Setter Property="FontSize" Value="12px"/>
    <Setter Property="FontWeight" Value="Bold"/>
    <Setter Property="Cursor" Value="Hand"/>
    <Setter Property="Foreground">
        <Setter.Value>
            <SolidColorBrush Opacity="1" Color="White"/>
        </Setter.Value>
    </Setter>
    <Setter Property="Background" >
        <Setter.Value>
            <SolidColorBrush Opacity="1" Color="#28C2FF" />
        </Setter.Value>
    </Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">

                <Border x:Name="border"
                         SnapsToDevicePixels="True"
                         BorderThickness="1"
                         Padding="4,2"
                         BorderBrush="Gray"
                         CornerRadius="3"
                         Background="{TemplateBinding Background}">
                    <Grid>
                        <ContentPresenter 
                        Margin="2"
                        HorizontalAlignment="Center"
                        VerticalAlignment="Center"
                        RecognizesAccessKey="True" />

                    </Grid>
                </Border>

            </ControlTemplate>
        </Setter.Value>
    </Setter>

    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="true">
            <Trigger.EnterActions>
                <BeginStoryboard>
                    <Storyboard>
                        <ColorAnimation To="#D2F898"
                                        Storyboard.TargetProperty="(Control.Background).(SolidColorBrush.Color)" 
                                        FillBehavior="HoldEnd" Duration="0:0:0.25" AutoReverse="False" RepeatBehavior="1x"/>
                    </Storyboard>
                </BeginStoryboard>
            </Trigger.EnterActions>

            <Trigger.ExitActions>
                <BeginStoryboard>
                    <Storyboard>
                        <ColorAnimation
                                            Storyboard.TargetProperty="(Control.Background).(SolidColorBrush.Color)" 
                                            FillBehavior="HoldEnd" Duration="0:0:0.25" AutoReverse="False" RepeatBehavior="1x"/>
                    </Storyboard>
                </BeginStoryboard>
            </Trigger.ExitActions>

        </Trigger>

    </Style.Triggers>
</Style>

il suffit d'appeler le style.

Exemple de mise en œuvre

<Button Style="{StaticResource Flat_Button}" Height="Auto"Width="Auto">  
     <StackPanel>
     <TextBlock Text="SAVE" FontFamily="Arial" FontSize="10.667"/>
     </StackPanel>
</Button>

3voto

Une réponse un peu plus difficile qui utilise ControlTemplate et a un effet d'animation (adapté de https://docs.microsoft.com/en-us/dotnet/framework/wpf/controls/customizing-the-appearance-of-an-existing-control )

Dans votre dictionnaire de ressources, définissez un modèle de contrôle pour votre bouton, comme celui-ci :

<ControlTemplate TargetType="Button" x:Key="testButtonTemplate2">
    <Border Name="RootElement">
        <Border.Background>
            <SolidColorBrush x:Name="BorderBrush" Color="Black"/>
        </Border.Background>

        <Grid Margin="4" >
            <Grid.Background>
                <SolidColorBrush x:Name="ButtonBackground" Color="Aquamarine"/>
            </Grid.Background>
            <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="4,5,4,4"/>
        </Grid>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CommonStates">
                <VisualState x:Name="Normal"/>
                <VisualState x:Name="MouseOver">
                    <Storyboard>
                        <ColorAnimation Storyboard.TargetName="ButtonBackground" Storyboard.TargetProperty="Color" To="Red"/>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="Pressed">
                    <Storyboard>
                        <ColorAnimation Storyboard.TargetName="ButtonBackground" Storyboard.TargetProperty="Color" To="Red"/>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </Border>
</ControlTemplate>

dans votre XAML, vous pouvez utiliser le modèle ci-dessus pour votre bouton comme ci-dessous :

Définissez votre bouton

<Button Template="{StaticResource testButtonTemplate2}" 
HorizontalAlignment="Center" VerticalAlignment="Center" 
Foreground="White">My button</Button>

J'espère que cela vous aidera

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X