Как удалить стандартный эффект наведения курсора на кнопки WPF?

87

Моя проблема в том, что в WPF всякий раз, когда я пытаюсь изменить цвет фона кнопки с помощью триггеров или анимации, эффект наведения мыши по умолчанию (серый с оранжевым свечением), кажется, имеет приоритет.

После долгих поисков я не знаю, как убрать этот эффект.

Неллиус
источник

Ответы:

17

Вам необходимо создать собственный шаблон пользовательской кнопки, чтобы иметь полный контроль над внешним видом во всех состояниях. Вот учебник .

Марк Хит
источник
2
Спасибо, это было прекрасно. Это было сложнее, чем я думал, но сейчас все работает хорошо.
Неллиус
19
По какой-то причине существует 100 ответов о создании настраиваемых шаблонов для элементов управления WPF, и все они без необходимости ошибочны. Нет причин бороться с написанием 50 строк кода шаблона для кнопки, чтобы изменить одну вещь. Все, что вам нужно сделать, это в конструкторе xaml щелкнуть правой кнопкой мыши элемент управления и создать копию кода шаблона. VS создаст стиль именно из этой кнопки, и вы сможете настроить его оттуда. Занимает буквально 2 секунды.
The Muffin Man
@TheMuffinMan Фантастически, но не кажется ли вам немного странным, что требуется 50 строк кода шаблона, чтобы кнопка не меняла цвет фона при наведении курсора мыши? Что за тупо сложный фреймворк WPF.
Эш
@Ash Или можно утверждать, что это ведет пользователя в том направлении, в котором они должны двигаться. Если у вас есть кнопка, для которой требуется новое состояние наведения, это, скорее всего, новый ТИП кнопки; возможно, кнопка навигации, кнопка на панели задач и т. д. Если это так, вам не следует изменять одноразовые свойства для нее, она должна иметь собственный элемент управления или группу стилей. И это то, что вас заставляет делать.
Мэтт Кенефик,
@TheMuffinMan: вы действительно человек! 10 лет работы с WPF и только что узнал о опции «Редактировать шаблон»!
Пол
109

Это похоже на решение, упомянутое Марком Хитом, но с меньшим количеством кода для создания очень простой кнопки без встроенного эффекта анимации мыши. Он сохраняет простой эффект наведения курсора мыши на отображение границы кнопки черным цветом.

Стиль можно вставить, например, в раздел Window.Resources или UserControl.Resources (как показано).

<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
источник
2
Мне очень нравится это решение. Однако триггеры наведения указателя мыши активируются только тогда, когда указатель мыши находится над текстом на кнопке. Я добавил текстовый блок заданной ширины внутри кнопки, чтобы исправить эту проблему.
Дэйв
Вы, сэр, святой.
krobelusmeetsyndra
26

Просто чтобы добавить очень простое решение, мне этого было достаточно, и я думаю, что это решает проблему OP. Я использовал решение в этом ответе, за исключением обычного Backgroundзначения вместо изображения.

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

Никаких повторных шаблонов, кроме принудительного Backgroundвсегда быть Transparentфоном из шаблонной кнопки - наведение мыши больше не влияет на фон, как только это будет сделано. Очевидно, замените Transparentна любое предпочтительное значение.

Lyall
источник
11

У Человека-маффина был очень простой ответ, который меня устроил.

Чтобы добавить немного более конкретного направления, по крайней мере, для VS 2013:

  • Щелкните правой кнопкой мыши элемент управления
  • Выберите Редактировать шаблон => Редактировать копию ...
  • Я выбрал "Приложение", чтобы сохранить стиль.
    • Отсюда вы можете напрямую редактировать App.xaml и видеть свойства с интуитивно понятными названиями. Для моих целей я просто установил RenderMouseOver = "False"
  • Затем в MainWindow.xaml или в другом месте вашего графического интерфейса вы можете вставить новый стиль в конец тега Button, например ... Style="{DynamicResource MouseOverNonDefault}"/>
Benji-Man
источник
Кто такой Маффин?
Mike W
СМЕШНО. Он дал второй ответ на вопрос, принятый владельцем. Не был уверен, серьезно вы спрашиваете или шутите. Трудно сказать с таким именем, как Muffin Man.
Benji-Man
6

Эта ссылка мне очень помогла http://www.codescratcher.com/wpf/remove-default-mouse-over-effect-on-wpf-buttons/

Определите стиль в UserControl.Resources или 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>

Затем добавьте стиль к своей кнопке таким образом 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

Если кто-то не хочет отменять шаблон управления по умолчанию, то вот решение.

Вы можете создать DataTemplate для кнопки, которая может иметь TextBlock, а затем вы можете написать триггер свойства в свойстве IsMouseOver, чтобы отключить эффект наведения мыши. Высота TextBlock и Button должна быть одинаковой.

<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

Расширение для ответа dodgy_coder, которое добавляет поддержку ..

  • Сохранение стиля кнопки WPF
  • Добавляет поддержку IsSelected и hover, т. Е. Переключаемую кнопку.

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

Примеры..

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

Stoj
источник
0

Использование триггера шаблона:

<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>
Лайне Микаэль
источник