Як змінити фон для кнопки наведення миші у WPF?


93

У мене є кнопка на моїй сторінці з цим 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>

Але коли я кладу мишу на свою кнопку, фон кнопки змінюється на сірий фон Windows за замовчуванням.
В чому проблема?

Це зображення кнопки до і після наведення курсора миші:
До:
Раніше
Після:
Після


Але ви повинні запустити зображення Forward-48.pngі викликати IsMouseOver, щоб змінити його на те саме Forward-48.png. Я намагаюся використовувати ваш код з різними зображеннями, і я все працював чудово.
Анатолій Миколаїв

1
@anatoliy: Це не працює.
Sepehr Mohammadi

Після - це ваш колір за замовчуванням? В іншому місці ви не змінюєте / не встановлюєте фон кнопки? У мене ваш код працює нормально.
Анатолій Миколаїв

Відповіді:


173

Щоб видалити MouseOverповедінку за замовчуванням, Buttonвам потрібно буде змінити файл ControlTemplate. Зміна вашого Styleвизначення на наступне має зробити трюк:

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

РЕДАГУВАТИ: Це запізнення на кілька років, але ви насправді можете встановити пензлик межі всередині межі, яка там знаходиться. Ідк, якщо на це вказували, але, схоже, це не було ...


1
Це працює, однак кнопка Межі зникне! Довелося розмістити елемент <Border BorderBrush = "DarkGray" BorderThickness = "1"> навколо кнопки.
Венугопал М

4
@CF причиною цього є стандартний стиль кнопки, який має тригери всередині ControlTemplate, тому вони замінюють Styleтригери OP .
торвін

1
@torvin Це здається таким відсталим! Чому визначений користувачем тригер повинен бути замінений типовим? Я розумію ієрархію, ControlTemplate стоїть над стилем, але я не розумію, чому так важко перевизначити такі базові параметри.
Fuselight

@Fuselight, тригер всередині в ControlTemplateосновному говорить: "Розфарбуй межу відповідно до Backgroundкольору. А якщо миша знаходиться над кнопкою - натомість зафарбуйте, що облямовує цей колір ', тоді як у стилі ви маєте доступ лише до Backgroundкольору, а не до основного кольору межі. Я бачу, що ви хочете сказати, що стиль WPF залишає бажати кращого ...
торвін

Це має додаткову перевагу при видаленні синього вікна, яке відображається при переносі, при використанні зображення з прозорим фоном. У моєму випадку я не хотів кордону, тому встановив BorderThickness на 0.
Чак Севедж

20

На сьогодні всі відповіді передбачають повну заміну поведінки кнопки за замовчуванням чимось іншим. Однак IMHO корисно і важливо розуміти, що можна змінити лише ту частину, яка вам важлива , відредагувавши існуючий шаблон за замовчуванням для елемента XAML.

У разі роботи з ширяння ефекту на кнопку WPF, зміна зовнішнього вигляду в WPF Buttonелемента викликано Triggerв стилі за замовчуванням для Button, яке засноване на IsMouseOverвласності і встановлює Backgroundі BorderBrushвластивості верхнього рівня Borderелемента у шаблоні управління. В Buttonтлі елемента знаходиться під Borderфоном елемента, тому зміна Button.Backgroundвластивості не заважає ефект польоту від перегляду.

Доклавши певних зусиль, ви можете замінити цю поведінку за допомогою власного сеттера, але оскільки елемент, на який вам потрібно впливати, знаходиться в шаблоні, а безпосередньо не доступний у вашому власному XAML, такий підхід буде складним, а IMHO надмірно складним.

Іншим варіантом було б використовувати графіку як Contentдля, Buttonа не як Background. Якщо вам потрібен додатковий вміст над графікою, ви можете поєднати їх із Gridоб’єктом верхнього рівня у вмісті.

Однак, якщо ви буквально просто хочете повністю вимкнути ефект наведення (а не просто приховувати його), ви можете скористатися Visual Studio XAML Designer:

  1. Під час редагування XAML виберіть вкладку "Дизайн" .
  2. На вкладці "Дизайн" знайдіть кнопку, для якої потрібно вимкнути ефект.
  3. Клацніть правою кнопкою миші та виберіть "Редагувати шаблон / Редагувати копію ..." . Виберіть у підказці, де ви отримаєте, де ви хочете розмістити новий ресурс шаблону. Здається, це нічого не робить, але насправді конструктор додав нові ресурси там, де ви це сказали, і змінив ваш елемент кнопки на посилання на стиль, який використовує ці ресурси як шаблон кнопки.
  4. Тепер ви можете редагувати цей стиль. Найпростіше видалити або залишити коментар (наприклад, Ctrl+ E, C)<Trigger Property="IsMouseOver" Value="true">...</Trigger> елемент. Звичайно, ви можете внести будь-які зміни в шаблон, який хочете на той момент.

Коли ви закінчите, стиль кнопки виглядатиме приблизно так:

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

(Примітка: ви можете опустити p: кваліфікацію простору імен XML у фактичному коді ... Я надаю їх тут лише тому, що XML-програвач форматування коду XML заплутається <Style/>елементами, які не мають повноцінного імені з простором імен XML.)

Якщо ви хочете застосувати той самий стиль до інших кнопок, ви можете просто клацнути їх правою кнопкою миші та вибрати «Редагувати шаблон / Застосувати ресурс» та вибрати стиль, який ви щойно додали для першої кнопки. Ви навіть можете зробити цей стиль типовим для всіх кнопок, використовуючи звичайні прийоми застосування стилю за замовчуванням до елементів у XAML.


5
Дуже дякую. Це єдина припустима відповідь тут
Джаред Біч

13

Це мені добре вдалось.

Стиль кнопки

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

Кнопка

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

Примітки

  • Кнопка відображає маленький синій хрестик, схожий на той, що використовується для закриття вікна.
  • Встановивши фон сітки на "Прозорий", він додає хіт, це означає, що якщо миша знаходиться де-небудь над кнопкою, вона буде працювати. Опустіть цей тег, і кнопка загориться, лише якщо миша знаходиться над однією з векторних ліній в піктограмі (це не дуже корисно).

1
Це чудова відповідь, але як щодо зміни Strokeкольору при наведенні курсора на екран Border, без того, щоб він наводився лише на Path?
Нейт

1
Ця x:Key="TransparentStyle"частина та використання були для мене важливими, щоб туди потрапити ... Дякую!
nrod

6

Просто хочу поділитися своїм стилем кнопок із мого ResourceD Dictionary, яким я користувався. Ви можете вільно змінювати фон onHover на тригерах стилю. Msgstr " ColorAnimation To = * ваш бажаний BG (тобто # FFCEF7A0)". Кнопка BG також автоматично повернеться до початкової величини BG після переходу миші. Ви навіть можете встановити швидкість переходу.

Ресурсний словник

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

все, що вам потрібно зробити, це назвати стиль.

Приклад реалізації

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

2

Трохи складніша відповідь, яка використовує ControlTemplate і має анімаційний ефект (адаптовано з https://docs.microsoft.com/en-us/dotnet/framework/wpf/controls/customizing-the-appearance-of-an-existing- контроль )

У вашому словнику ресурсів визначте шаблон управління для вашої кнопки, як цей:

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

у вашому XAML ви можете використовувати шаблон вище для вашої кнопки, як показано нижче:

Визначте свою кнопку

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

Сподіваюся, це допоможе


0

Для зміни стилю кнопки

1-е: визначте стилі ресурсів

<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-й код коду кнопки

                           <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-й код позаду

    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;

        }
    }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.