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

迁移Xamarin至MAUI:如何创建正方形SKCanvasView?

解决MAUI中SKCanvasView正方形显示问题的方案

核心问题分析

MAUI的布局测量逻辑与Xamarin存在差异,直接绑定Grid宽高到HeightRequest/WidthRequest无法准确同步布局变化,导致画布比例失衡、初始不显示、旋转时内容超出边界等问题。

具体修复步骤

1. 调整XAML布局,添加尺寸变化事件

删除SKCanvasView原有HeightRequest和WidthRequest的绑定,新增SizeChanged事件监听:

<skia:SKCanvasView x:Name="CanvasView" 
                   PaintSurface="OnPaintSurface"
                   SizeChanged="OnCanvasViewSizeChanged"
                   HorizontalOptions="Fill"
                   VerticalOptions="Fill"/>

同时确保父级Grid占满可用空间:

<Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
    <skia:SKCanvasView x:Name="CanvasView" .../>
    <Label .../> <!-- Label保持叠加在CanvasView上层 -->
</Grid>

2. 后台代码强制正方形约束

在OnCanvasViewSizeChanged事件中,取Grid可用宽高的最小值,强制设置SKCanvasView的尺寸为该值,确保正方形比例:

private void OnCanvasViewSizeChanged(object sender, EventArgs e)
{
    if (sender is SKCanvasView canvas && Parent is Grid grid)
    {
        var squareSize = Math.Min(grid.Width, grid.Height);
        canvas.WidthRequest = squareSize;
        canvas.HeightRequest = squareSize;
        canvas.InvalidateMeasure();
    }
}

3. 修正画布绘制逻辑

在PaintSurface事件中,以正方形区域为基准绘制内容,避免偏移或超出:

private void OnPaintSurface(object sender, SKPaintSurfaceEventArgs e)
{
    var canvas = e.Surface.Canvas;
    canvas.Clear();

    // 计算正方形区域尺寸
    var squareSize = Math.Min(e.Info.Width, e.Info.Height);
    var squareRect = new SKRect(0, 0, squareSize, squareSize);
    
    // 将画布平移到父容器中心,确保正方形居中
    canvas.Translate((e.Info.Width - squareSize)/2, (e.Info.Height - squareSize)/2);

    // 在这里执行SVG和Label的绘制逻辑,基于squareRect区域进行等比例缩放
    // ...
}

4. 移除冗余布局属性

删除SKCanvasView上可能限制尺寸的固定布局属性(如HorizontalOptions="Center"),让它能根据设置的WidthRequest/HeightRequest自适应。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 18:17:10