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

MAUI中如何将DrawingView置于ScrollView上方且位置不变以解决绘图延迟问题

MAUI中如何将DrawingView置于ScrollView上方且位置不变以解决绘图延迟问题

我来帮你搞定这个绘图延迟的问题!你遇到的核心问题其实是ScrollView的触摸事件优先级更高——它需要花一小段时间判断你是要滚动页面还是操作子视图,这就导致DrawingView的响应慢了半拍。要解决这个问题,我们需要让DrawingView直接接收触摸事件,同时保持它和原来完全一致的位置(包括ScrollView滚动时也能同步位置)。

下面是具体的解决方案:

方案步骤

  1. 调整布局层级:把DrawingView从ScrollView内部的Grid中移出来,放到和ScrollView同级的外层Grid里,让它覆盖在ScrollView上方。
  2. 同步滚动位置:通过绑定ScrollView的滚动偏移量,让DrawingView在ScrollView滚动时自动跟随,保持相对位置不变。
  3. 禁用ScrollView的滚动干扰:在绘图开始时暂时禁用ScrollView的滚动,结束后恢复,避免触摸冲突。

修改后的完整XAML代码

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="EaaDigitalSigningApp.Views.YeMinorWaiverPage"
             xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
             xmlns:local="clr-namespace:EaaDigitalSigningApp.Views"
             Shell.BackgroundColor="{StaticResource EaaBlue}"
             Title="Waiver Page">

    <ContentPage.Resources>
        <!-- 自定义转换器:用于计算DrawingView的顶部位置 -->
        <local:AddValueConverter x:Key="AddValueConverter" />
    </ContentPage.Resources>

    <Shell.BackButtonBehavior>
        <BackButtonBehavior Command="{Binding BackCommand}"/>
    </Shell.BackButtonBehavior>

    <!-- 外层Grid,让ScrollView和DrawingView重叠 -->
    <Grid>
        <!-- 原有的ScrollView,移除内部的DrawingView -->
        <ScrollView x:Name="SigningScrollView" HorizontalOptions="CenterAndExpand" WidthRequest="800" IsEnabled="True" >
            <Grid Padding="20,0,0,0" Margin="0,0,0,0" >
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>

                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>

                <!-- 合同内容WebView -->
                <WebView x:Name="Webview" InputTransparent="True" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" HeightRequest="1825"  VerticalOptions="End" HorizontalOptions="FillAndExpand"/>

                <!-- 移除原来的DrawingView,移到外层Grid -->

                <Label Grid.Row="2" Grid.Column="0" HorizontalOptions="Start" Text="{Binding  parentSignatureText}" x:Name="ParentSignatureText" FontSize="Micro" />

                <StackLayout Grid.Row="3" Grid.Column="0" HorizontalOptions="Start">
                    <Label x:Name="ParentOrGuardiansPrintedName" VerticalTextAlignment="End" Text="{Binding YeWaiver.Signee.FullNameFirstLast}" />
                    <Label Text="{Binding PrintParentSignatureText}" x:Name="PrintParentSignatureText" FontSize="Micro" />
                </StackLayout>

                <StackLayout Grid.Row="3" Grid.Column="1" HorizontalOptions="Center">
                    <Label x:Name="MinorParticipantsPrintedName" Text="{Binding YeWaiver.Signee.AssociatedMinorFullNameFirstLast}" />
                    <Label Text="Minor Participant's Name" IsVisible="{Binding MinorSignatureTextVisible}" x:Name="MinorSignatureText" FontSize="Micro"/>
                </StackLayout>

                <StackLayout Grid.Row="3" Grid.Column="2" HorizontalOptions="Center">
                    <Label x:Name="DateOfSignature" Text="{Binding ContractDate}"/>
                    <Label Text="Date" FontSize="Micro" VerticalOptions="Start" />
                </StackLayout>

                <Button Grid.Row="4" Margin="5" Grid.Column="0" Grid.ColumnSpan="3" FontSize="Large" x:Name="ReviewAndSignDocument" Text="Complete Signing And Next Document" Command="{Binding ReviewAndSignCommand}" BackgroundColor="{StaticResource EaaBlue}" TextColor="White" />

                <Button Grid.Row="5" Margin="5" Grid.Column="0" Grid.ColumnSpan="3"  FontSize="Large" x:Name="SkipDocument" Text="Skip this Youth >>" IsVisible="{Binding SkipDocumentVisible}" IsEnabled="{Binding SkipDocumentEnabled}"  Command="{Binding SkipDocumentCommand}" BackgroundColor="{StaticResource EaaBlue}" TextColor="White"  />
            </Grid>
        </ScrollView>

        <!-- 移到外层的DrawingView,绑定位置同步滚动 -->
        <toolkit:DrawingView x:Name="drawingView" 
                             Margin="20, {Binding Source={x:Reference SigningScrollView}, Path=ScrollY, Converter={StaticResource AddValueConverter}, ConverterParameter=1825}, 0, 0"
                             WidthRequest="780"  <!-- 800 - 左边Padding20 -->
                             HeightRequest="200"
                             BackgroundColor="BlanchedAlmond"
                             DrawingLineCompleted="DrawingView_DrawingLineCompleted"
                             DrawingStarted="DrawingView_DrawingStarted"
                             Lines="{Binding Signature}" 
                             IsMultiLineModeEnabled="True"
                             ShouldClearOnFinish="False" />
    </Grid>
</ContentPage>

补充代码实现

  1. 添加值转换器:创建一个AddValueConverter类,用于计算DrawingView的顶部位置(ScrollView的滚动偏移量 + WebView的高度):
namespace EaaDigitalSigningApp.Views
{
    public class AddValueConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value is double scrollY && double.TryParse(parameter?.ToString() ?? "0", out double addValue))
            {
                return scrollY + addValue;
            }
            return 0;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}
  1. 处理绘图事件:在后台代码中添加绘图开始和结束的事件,控制ScrollView的启用状态:
private void DrawingView_DrawingStarted(object sender, EventArgs e)
{
    // 绘图开始时禁用ScrollView,防止滚动干扰
    SigningScrollView.IsEnabled = false;
}

private void DrawingView_DrawingLineCompleted(object sender, CommunityToolkit.Maui.Core.DrawingLineCompletedEventArgs e)
{
    // 绘图结束后恢复ScrollView的滚动功能
    SigningScrollView.IsEnabled = true;
}

为什么这个方案有效?

  • 层级调整:DrawingView现在在ScrollView的视觉层级上方,触摸事件会直接被它接收,跳过了ScrollView的触摸判断延迟。
  • 位置同步:通过绑定ScrollView的ScrollY属性,DrawingView会跟着ScrollView一起滚动,完全保持原来的相对位置。
  • 滚动拦截:绘图时禁用ScrollView,避免用户在绘图时不小心触发滚动,提升交互体验。

备注:内容来源于stack exchange,提问作者Justin Sinnard

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 11:08:09