web-dev-qa-db-fra.com

Comment modifier 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 l'arrière-plan 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

78
Sepehr Mohammadi

Pour supprimer le comportement par défaut de MouseOver sur Button, vous devez modifier le comportement de ControlTemplate. Modifier votre définition de Style par 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: Il y a quelques années de retard, mais vous êtes en mesure de définir le contour de la bordure à l'intérieur de la frontière. Idk si cela a été signalé, mais cela ne semble pas être le cas ...

145
Richard E

Jusqu'à présent, toutes les réponses impliquent de remplacer complètement le comportement du bouton par défaut par autre chose. Cependant, à mon humble avis, il est utile et important de comprendre qu’il est possible de modifier niquement la partie qui vous tient à cœur, en modifiant le modèle par défaut existant pour un élément XAML.

Dans le cas de l’effet de survol sur un bouton WPF, le changement d’apparence dans un élément WPF Button est provoqué par un Trigger dans le style par défaut du Button, qui est sur la base de la propriété IsMouseOver et définit les propriétés Background et BorderBrush de l'élément Border de niveau supérieur dans le modèle de contrôle. L'arrière-plan de l'élément Button se trouve sous l'arrière-plan de l'élément Border. Par conséquent, le fait de modifier la propriété Button.Background n'empêche pas l'affichage du survol.

Avec un peu d’effort, vous pouvez remplacer ce comportement par votre propre installateur, mais étant donné que l’élément que vous devez affecter se trouve dans le modèle et n’est pas directement accessible dans votre propre code XAML, cette approche serait difficile et extrêmement complexe.

Une autre option serait d'utiliser le graphique en tant que Content pour le Button plutôt que le Background. Si vous avez besoin de contenu supplémentaire sur le graphique, vous pouvez les combiner avec un objet Grid en tant qu'objet de niveau supérieur dans le contenu.

Toutefois, si vous souhaitez simplement désactiver complètement l'effet de survol (plutôt que de le masquer), vous pouvez utiliser le concepteur XAML de Visual Studio:

  1. Lors de l'édition de votre XAML, sélectionnez l'onglet "Conception".
  2. Dans l'onglet "Conception", recherchez le bouton pour lequel vous souhaitez désactiver l'effet.
  3. Cliquez avec le bouton droit de la souris sur ce bouton, puis choisissez "Modifier le modèle/Modifier une copie ...". Sélectionnez dans l'invite où vous voulez placer la nouvelle ressource de modèle. Cela semblera ne rien faire, mais en réalité, le concepteur aura ajouté de nouvelles ressources là où vous l'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 exemple Ctrl+EC) l’élément <Trigger Property="IsMouseOver" Value="true">...</Trigger>. Bien sûr, vous pouvez modifier le modèle souhaité à ce stade.

Lorsque vous avez terminé, le style du bouton ressemblera à 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>

(Remarque: vous pouvez omettre les qualifications p: XML dans le code réel. Je ne les fournis ici que parce que le formateur de code XML Stack Overflow est confondu par les éléments <Style/> qui ne possèdent pas de nom qualifié complet. nom avec un espace de noms XML.)

Si vous souhaitez appliquer le même style à d'autres boutons, vous pouvez simplement cliquer dessus avec le bouton droit de la souris et choisir "Modifier le modèle/Appliquer la ressource" et sélectionner le style que vous venez d'ajouter pour le premier bouton. Vous pouvez même définir ce style comme style par défaut pour tous les boutons, en utilisant les techniques habituelles pour appliquer un style par défaut aux éléments en XAML.

11
Peter Duniho

Cela a bien fonctionné pour moi.

Style de bouton

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

Remarques

  • Le bouton affiche une petite croix bleue, très semblable à celle utilisée pour fermer une fenêtre.
  • En définissant l'arrière-plan de la grille sur "Transparent", cela ajoute un minimum, ce qui signifie que si la souris est n'importe où sur le bouton, cela fonctionnera. Omettez cette balise, et le bouton ne s'allumera que si la souris survole l'une des lignes vectorielles de l'icône (ce n'est pas très utilisable).
10
Contango

Je veux juste partager mon style de bouton de mon ResourceDictionary que j'ai utilisé. Vous pouvez modifier librement l’arrière-plan onHover au niveau des déclencheurs de style. " ColorAnimation To = * votre BG souhaité (c'est-à-dire # FFCEF7A0)". Le bouton BG retrouvera également automatiquement son glycémie d'origine après l'état mouseOver. Vous pouvez même définir la rapidité de la transition.

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

tout ce que vous avez à faire est d'appeler le style.

Exemple d'implémentation

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

Une réponse légèrement plus difficile utilisant ControlTemplate et produisant un effet d’animation (adapté de https://docs.Microsoft.com/en-us/dotnet/framework/wpf/controls/customizing-the-appearance-of- un-contrôle-existant )

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éfinir votre bouton

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

J'espère que ça aide

2
Iakobos Karakizas

Pour changer de style de bouton

1er: définir les styles de ressources

<Window.Resources>

    <Style x:Key="OvergroundIn" TargetType="Button">

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Grid Background="#FF16832F">
                        <ContentPresenter TextBlock.Foreground="White" TextBlock.TextAlignment="Center" Margin="0,8,0,0" ></ContentPresenter>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>

        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">

                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="Button">
                            <Grid Background="#FF06731F">
                                <ContentPresenter TextBlock.Foreground="White" TextBlock.TextAlignment="Center" Margin="0,8,0,0" ></ContentPresenter>
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>

            </Trigger>
        </Style.Triggers>

    </Style>

    <Style x:Key="OvergroundOut" TargetType="Button">

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Grid Background="#FFF35E5E">
                        <ContentPresenter TextBlock.Foreground="White" TextBlock.TextAlignment="Center" Margin="0,8,0,0" ></ContentPresenter>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>

        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">

                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="Button">
                            <Grid Background="#FFE34E4E">
                                <ContentPresenter TextBlock.Foreground="White" TextBlock.TextAlignment="Center" Margin="0,8,0,0" ></ContentPresenter>
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>

            </Trigger>
        </Style.Triggers>

    </Style>


</Window.Resources>

2ème définir le code du bouton

                           <Border Grid.Column="2" BorderBrush="LightGray" BorderThickness="2" CornerRadius="3" Margin="2,2,2,2"  >
                                <Button Name="btnFichar" BorderThickness="0" Click="BtnFichar_Click">
                                    <Button.Content>
                                        <Grid>
                                            <TextBlock Margin="0,7,0,7" TextAlignment="Center">Fichar</TextBlock> 
                                        </Grid>
                                    </Button.Content>
                                </Button>
                            </Border>

3ème code derrière

    public void ShowStatus()
    {
        switch (((MainDto)this.DataContext).State)
        {
            case State.IN:
                this.btnFichar.BorderBrush = new SolidColorBrush(Color.FromRgb(243, 94, 94));
                this.btnFichar.Style = Resources["OvergroundIn"] as Style;
                this.btnFichar.Content = "Fichar Salida";
                break;

            case State.OUT:
                this.btnFichar.BorderBrush = new SolidColorBrush(Color.FromRgb(76, 106, 83));
                this.btnFichar.Style = Resources["OvergroundOut"] as Style;
                this.btnFichar.Content = "Fichar Entrada";
                break;

        }
    }
0
Ángel Ibáñez