前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >WPF中Button空白区域无法点击的解决方法

WPF中Button空白区域无法点击的解决方法

作者头像
码客说
发布2023-04-12 13:22:25
1.2K0
发布2023-04-12 13:22:25
举报
文章被收录于专栏:码客码客

前言

WPF的Button有一点特别奇怪的地方是

当您单击按钮的空白区域时,该按钮不会触发 Click 事件,因为该事件只会在按钮的可见内容区域内发生。

解决方式有两种

  1. 改变可见区域。
  2. 使用PreviewMouseDown事件中触发Click事件。

推荐使用第一种方法,第二种按钮的悬浮样式依旧不会触发。

方式1

改变可见区域

核心代码

代码语言:javascript
复制
<Button Content="My Button">
    <Button.Template>
        <ControlTemplate TargetType="Button">
            <Grid Background="Transparent">
                <ContentPresenter />
            </Grid>
        </ControlTemplate>
    </Button.Template>
</Button>

就是在Button内部渲染区域的外层添加了一个Grid,并且设置背景色为Transparent

优点奇葩的是

这个背景色必须设置,即使是设置的透明色,也算是可见区域了。

完整自定义按钮代码如下:

StyleZRoundButton.xaml

代码语言:javascript
复制
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:ZView">
    <Style x:Key="ZRoundButtonStyle" TargetType="{x:Type local:ZRoundButton}">
        <Setter Property="OverridesDefaultStyle" Value="True" />
        <Setter Property="Cursor" Value="Hand" />
        <Setter Property="FocusVisualStyle" Value="{x:Null}" />
        <Setter Property="HorizontalContentAlignment" Value="Center" />
        <Setter Property="VerticalContentAlignment" Value="Center" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Grid Background="Transparent">
                        <Border
                            Name="border"
                            Padding="{TemplateBinding Padding}"
                            HorizontalAlignment="Stretch"
                            VerticalAlignment="Stretch"
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            CornerRadius="{Binding Path=BorderRadius, RelativeSource={RelativeSource TemplatedParent}}"
                            IsHitTestVisible="True">
                            <ContentPresenter
                                Margin="{TemplateBinding Padding}"
                                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
                        </Border>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Opacity" Value="0.6" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

ZRoundButton.cs

代码语言:javascript
复制
using System.Windows;
using System.Windows.Controls;

namespace ZView
{
    internal class ZRoundButton : Button
    {
        public int BorderRadius
        {
            get { return (int)GetValue(BorderRadiusProperty); }
            set { SetValue(BorderRadiusProperty, value); }
        }

        public static readonly DependencyProperty BorderRadiusProperty = DependencyProperty.Register(
            "BorderRadius", 
            typeof(int), 
            typeof(ZRoundButton), 
            new FrameworkPropertyMetadata()
        );
    }
}

方式2

要在单击按钮的任何位置时都触发 Click 事件,您可以使用 PreviewMouseDown 事件。该事件会在鼠标按下时触发,并在 Click 事件之前发生。

您可以通过以下方式将 PreviewMouseDown 事件处理程序绑定到按钮:

代码语言:javascript
复制
<Button Content="My Button" PreviewMouseDown="Button_PreviewMouseDown" Click="Button_Click"/>

然后,在您的代码中实现 Button_PreviewMouseDown 和 Button_Click 事件处理程序。

在 Button_PreviewMouseDown 处理程序中,您可以使用以下代码触发 Click 事件:

代码语言:javascript
复制
private void Button_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    if (e.ChangedButton == MouseButton.Left)
    {
        Button button = (Button)sender;
        button.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
    }
}

这将在单击按钮的任何位置时触发 Click 事件。

请注意,如果您希望仅在单击左键时触发 Click 事件,则可以使用上面示例代码中的 if 语句来检查 e.ChangedButton 的值。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-04-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 方式1
  • 方式2
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档