You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET MAUI中如何实现视觉元素(如按钮)的鼠标悬停检测

.NET MAUI 检测鼠标悬停状态的实现方法

.NET MAUI 没有直接提供 OnMouseOver 或 IsMouseOver 这类API,但可以通过以下几种方式实现鼠标悬停状态的检测和UI处理:

1. 使用 PointerEntered/PointerExited 事件

这是最直接的方式,利用MAUI内置的指针事件追踪鼠标进入和离开元素的状态:

XAML 代码

<Button Text="测试按钮" 
        PointerEntered="Button_PointerEntered"
        PointerExited="Button_PointerExited"/>

后台C# 代码

private bool _isMouseOver;

private void Button_PointerEntered(object sender, PointerEventArgs e)
{
    // 仅处理鼠标输入,排除触摸等其他指针类型
    if (e.PointerDeviceType != PointerDeviceType.Mouse) return;
    
    _isMouseOver = true;
    // 自定义悬停逻辑,比如修改按钮样式
    if (sender is Button btn)
    {
        btn.BackgroundColor = Colors.LightBlue;
    }
}

private void Button_PointerExited(object sender, PointerEventArgs e)
{
    if (e.PointerDeviceType != PointerDeviceType.Mouse) return;
    
    _isMouseOver = false;
    // 恢复默认状态
    if (sender is Button btn)
    {
        btn.BackgroundColor = Colors.Default;
    }
}

2. 用 VisualStateManager 实现纯UI状态切换

如果只需要修改UI样式(比如颜色、字体),不需要后台逻辑,可以直接利用MAUI内置的 PointerOver 视觉状态:

<Button Text="悬停样式按钮">
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="CommonStates">
            <VisualState x:Name="Normal">
                <VisualState.Setters>
                    <Setter Property="BackgroundColor" Value="Default"/>
                    <Setter Property="TextColor" Value="Black"/>
                </VisualState.Setters>
            </VisualState>
            <VisualState x:Name="PointerOver">
                <VisualState.Setters>
                    <Setter Property="BackgroundColor" Value="LightBlue"/>
                    <Setter Property="TextColor" Value="DarkBlue"/>
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
</Button>

MAUI会自动在鼠标悬停时切换到 PointerOver 状态,离开时恢复到 Normal 状态,无需编写后台代码。

3. 封装附加属性实现复用

如果需要在多个控件上复用悬停状态检测逻辑,可以封装一个附加属性,方便在XAML中绑定:

附加属性代码

using Microsoft.Maui.Controls;

namespace YourAppNamespace
{
    public static class MouseOverHelpers
    {
        public static readonly BindableProperty IsMouseOverProperty =
            BindableProperty.CreateAttached(
                "IsMouseOver",
                typeof(bool),
                typeof(MouseOverHelpers),
                false,
                BindingMode.TwoWay);

        public static bool GetIsMouseOver(BindableObject view)
            => (bool)view.GetValue(IsMouseOverProperty);

        public static void SetIsMouseOver(BindableObject view, bool value)
            => view.SetValue(IsMouseOverProperty, value);

        public static readonly BindableProperty TrackMouseOverProperty =
            BindableProperty.CreateAttached(
                "TrackMouseOver",
                typeof(bool),
                typeof(MouseOverHelpers),
                false,
                propertyChanged: OnTrackMouseOverChanged);

        public static bool GetTrackMouseOver(BindableObject view)
            => (bool)view.GetValue(TrackMouseOverProperty);

        public static void SetTrackMouseOver(BindableObject view, bool value)
            => view.SetValue(TrackMouseOverProperty, value);

        private static void OnTrackMouseOverChanged(BindableObject bindable, object oldValue, object newValue)
        {
            if (bindable is not VisualElement element) return;

            if ((bool)newValue)
            {
                element.PointerEntered += OnPointerEntered;
                element.PointerExited += OnPointerExited;
            }
            else
            {
                element.PointerEntered -= OnPointerEntered;
                element.PointerExited -= OnPointerExited;
            }
        }

        private static void OnPointerEntered(object sender, PointerEventArgs e)
        {
            if (sender is BindableObject view && e.PointerDeviceType == PointerDeviceType.Mouse)
                SetIsMouseOver(view, true);
        }

        private static void OnPointerExited(object sender, PointerEventArgs e)
        {
            if (sender is BindableObject view && e.PointerDeviceType == PointerDeviceType.Mouse)
                SetIsMouseOver(view, false);
        }
    }
}

使用示例

先在XAML头部引入命名空间:

xmlns:local="clr-namespace:YourAppNamespace"

然后给控件绑定附加属性:

<Button Text="复用悬停状态按钮"
        local:MouseOverHelpers.TrackMouseOver="True"
        BackgroundColor="{Binding Source={RelativeSource Self}, Path=(local:MouseOverHelpers.IsMouseOver), 
                          Converter={StaticResource BoolToColorConverter}}"/>

这里需要配合一个布尔转颜色的转换器,实现根据悬停状态自动切换背景色。

内容的提问来源于stack exchange,提问作者Siddharth R

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 18:45:49