如何在.NET MAUI Blazor Hybrid中检测滑动手势?
在.NET MAUI Blazor Hybrid中检测滑动手势的两种实现方法
方法一:结合原生.NET MAUI手势识别器(页面/全局级滑动)
这种方式利用原生MAUI的SwipeGestureRecognizer,适合监听整个BlazorWebView的滑动事件,再将事件传递给Blazor组件。
- 在MainPage.xaml中添加手势识别器
给BlazorWebView附加滑动手势识别器,指定监听的方向和事件处理方法:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:blazor="clr-namespace:Microsoft.AspNetCore.Components.WebView.Maui;assembly=Microsoft.AspNetCore.Components.WebView.Maui" x:Class="YourAppNamespace.MainPage"> <BlazorWebView HostPage="wwwroot/index.html"> <BlazorWebView.RootComponents> <RootComponent Selector="#app" ComponentType="{x:Type local:Main}" /> </BlazorWebView.RootComponents> <BlazorWebView.GestureRecognizers> <SwipeGestureRecognizer Direction="Left" Swiped="OnSwipedLeft" /> <SwipeGestureRecognizer Direction="Right" Swiped="OnSwipedRight" /> <SwipeGestureRecognizer Direction="Up" Swiped="OnSwipedUp" /> <SwipeGestureRecognizer Direction="Down" Swiped="OnSwipedDown" /> </BlazorWebView.GestureRecognizers> </BlazorWebView> </ContentPage>
- 在MainPage.xaml.cs中实现事件处理与跨端通知
通过IJSRuntime将滑动事件传递给Blazor端:
using Microsoft.AspNetCore.Components.WebView.Maui; using Microsoft.JSInterop; namespace YourAppNamespace; public partial class MainPage : ContentPage { [Inject] public IJSRuntime JSRuntime { get; set; } private async void OnSwipedLeft(object sender, SwipedEventArgs e) { await JSRuntime.InvokeVoidAsync("notifySwipe", "left"); } private async void OnSwipedRight(object sender, SwipedEventArgs e) { await JSRuntime.InvokeVoidAsync("notifySwipe", "right"); } private async void OnSwipedUp(object sender, SwipedEventArgs e) { await JSRuntime.InvokeVoidAsync("notifySwipe", "up"); } private async void OnSwipedDown(object sender, SwipedEventArgs e) { await JSRuntime.InvokeVoidAsync("notifySwipe", "down"); } }
- 添加JS桥接逻辑
在wwwroot/js/app.js中定义接收原生通知的方法,并触发Blazor可监听的自定义事件:
window.notifySwipe = function(direction) { const swipeEvent = new CustomEvent('swipe', { detail: direction }); document.dispatchEvent(swipeEvent); };
- 在Blazor组件中监听滑动事件
在目标Blazor组件(如Main.razor)中注册事件监听,并处理滑动逻辑:
@page "/" @inject IJSRuntime JSRuntime <h1>全局滑动监听演示</h1> <p>最后一次滑动方向:@lastSwipeDirection</p> @code { private string lastSwipeDirection = "无"; protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { await JSRuntime.InvokeVoidAsync("addEventListener", "swipe", args => DotNetObjectReference.Create(this).InvokeAsync<string>("HandleSwipe", args.detail)); } } [JSInvokable] public void HandleSwipe(string direction) { lastSwipeDirection = direction; StateHasChanged(); } }
方法二:纯Web端触摸事件监听(组件级滑动)
如果只需要监听特定Blazor组件内的滑动,可以直接通过JS触摸事件实现,无需依赖原生MAUI手势。
- Blazor组件中设置监听容器
在组件中定义需要监听滑动的容器,并通过JSInterop绑定监听逻辑:
@page "/" @inject IJSRuntime JSRuntime <div @ref="swipeContainer" class="swipe-area"> <p>组件内滑动方向:@lastSwipeDirection</p> </div> <style> .swipe-area { width: 100%; height: 70vh; border: 1px solid #ddd; display: flex; align-items: center; justify-content: center; background-color: #f5f5f5; } </style> @code { private ElementReference swipeContainer; private string lastSwipeDirection = "无"; protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { await JSRuntime.InvokeVoidAsync("setupComponentSwipeListener", swipeContainer, DotNetObjectReference.Create(this)); } } [JSInvokable] public void OnComponentSwipe(string direction) { lastSwipeDirection = direction; StateHasChanged(); } }
- 添加JS滑动检测逻辑
在wwwroot/js/app.js中实现触摸事件的监听与滑动方向判断:
window.setupComponentSwipeListener = function(element, dotNetRef) { let startX = 0; let startY = 0; const minSwipeThreshold = 60; // 最小滑动距离,过滤误触 element.addEventListener('touchstart', e => { startX = e.changedTouches[0].clientX; startY = e.changedTouches[0].clientY; }); element.addEventListener('touchend', e => { const endX = e.changedTouches[0].clientX; const endY = e.changedTouches[0].clientY; const diffX = endX - startX; const diffY = endY - startY; if (Math.abs(diffX) > Math.abs(diffY)) { // 水平滑动 if (Math.abs(diffX) > minSwipeThreshold) { dotNetRef.invokeMethodAsync('OnComponentSwipe', diffX > 0 ? '右' : '左'); } } else { // 垂直滑动 if (Math.abs(diffY) > minSwipeThreshold) { dotNetRef.invokeMethodAsync('OnComponentSwipe', diffY > 0 ? '下' : '上'); } } }); };
内容的提问来源于stack exchange,提问作者alive
相关产品推荐
相关产品推荐

