【问题标题】:How to remove default mouse-over effect on WPF buttons?如何删除 WPF 按钮上的默认鼠标悬停效果?
【发布时间】:2011-04-20 17:43:45
【问题描述】:

我的问题是,在 WPF 中,每当我尝试使用触发器或动画更改按钮背景的颜色时,默认的鼠标悬停效果(带有橙色光晕的灰色)似乎具有优先权。

经过大量搜索后,我对如何消除这种影响一无所知。

【问题讨论】:

    标签: wpf button mouseover


    【解决方案1】:

    您需要创建自己的自定义按钮模板才能完全控制所有状态的外观。这是tutorial

    【讨论】:

    • 谢谢,太完美了。做起来比我想象的要复杂,但现在一切正常。
    • 出于某种原因,有 100 个关于为 WPF 控件创建自定义模板的答案,它们都是不必要的错误。没有理由为一个按钮编写 50 行模板代码来改变一件事情。您所要做的就是在 xaml 设计器中右键单击控件并创建模板代码的副本。 VS 将从那个确切的按钮创建一个样式,你可以从那里调整它。实际上需要 2 秒。
    • @TheMuffinMan 太棒了,但您是否觉得有点奇怪,需要 50 行模板代码才能阻止按钮在鼠标悬停时更改背景颜色? WPF 是多么愚蠢的复杂框架。
    • @Ash 或者有人会争辩说它正在引导用户朝着他们应该前进的方向前进。如果你有一个按钮需要一个新的悬停状态,那很可能是一个新的按钮类型;也许是导航按钮、托盘按钮等。如果是这样,您不应该为它修改一次性属性,它应该有自己的控件或样式组。这就是让你这样做的原因。
    • @TheMuffinMan:你真的是那个男人!使用 WPF 10 年,刚刚发现“编辑模板”选项!
    【解决方案2】:

    这类似于 Mark Heath 提到的解决方案,但没有那么多代码来创建一个非常基本的按钮,没有内置的鼠标悬停动画效果。它保留了以黑色显示按钮边框的简单鼠标悬停效果。

    例如,样式可以插入到 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>
    

    【讨论】:

    • 我非常喜欢这个解决方案。但是,鼠标悬停触发器仅在鼠标悬停在按钮上的文本上时才会激活。我在按钮内添加了一个指定宽度的文本块来解决这个问题。
    • 你先生是个圣人。
    【解决方案3】:

    如果有人不想覆盖默认控制模板,那么这里就是解决方案。

    您可以为可以具有 TextBlock 的按钮创建 DataTemplate,然后您可以在 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>
    

    【讨论】:

      【解决方案4】:

      dodgy_coder 答案的扩展,增加了对..的支持。

      • 维护 WPF 按钮样式
      • 添加对 IsSelected 和悬停的支持,即切换按钮

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

      【讨论】:

        【解决方案5】:

        使用模板触发器:

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

        【讨论】:

          【解决方案6】:

          只是添加一个非常简单的解决方案,这对我来说已经足够了,我认为解决了 OP 的问题。我使用了解决方案in this answer,除了使用常规的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

          【讨论】:

            【解决方案7】:

            松饼人有一个非常简单的答案,对我有用。

            添加一些更具体的方向,至少对于 VS 2013:

            • 右键单击控件
            • 选择编辑模板 => 编辑副本...
            • 我选择了“应用程序”来保存样式
              • 您可以从这里直接编辑 App.xaml 并查看直观命名的属性。出于我的目的,我只是设置了 RenderMouseOver="False"
            • 然后,在 MainWindow.xaml 或 GUI 所在的任何位置,您可以将新样式粘贴到 Button 标记的末尾,例如... Style="{DynamicResource MouseOverNonDefault}"/&gt;

            【讨论】:

            • 谁是松饼人?
            • 哈哈。他对问题所有者接受的答案进行了第二次回复。不知道你问的是认真的还是开玩笑的。很难用像松饼人这样的名字来分辨。
            【解决方案8】:

            这个链接对我帮助很大 http://www.codescratcher.com/wpf/remove-default-mouse-over-effect-on-wpf-buttons/

            UserControl.ResourcesWindow.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>
            

            【讨论】:

              猜你喜欢
              • 2013-01-17
              • 2013-06-15
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-06-20
              • 1970-01-01
              • 2013-08-09
              相关资源
              最近更新 更多