mono / SkiaSharp

SkiaSharp is a cross-platform 2D graphics API for .NET platforms based on Google's Skia Graphics Library. It provides a comprehensive 2D API that can be used across mobile, server and desktop models to render images.
MIT License
4.52k stars 540 forks source link

[BUG] "Microsoft.UI.Xaml.Controls.Frame.NavigationFailed was unhandled." #2420

Open Dave-Quick opened 1 year ago

Dave-Quick commented 1 year ago

Description I get the above error message whenever I attempt to use the SKCanvasView control. Comment it out , it works normally, and the button appears. Uncomment it out and the problem returns.

Code

<!-- MainPage.xaml -->
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:skia="clr-namespace:SkiaSharp.Views.Maui.Controls;assembly=SkiaSharp.Views.Maui.Controls"            
             x:Class="TestSKCanvasView.MainPage">
    <StackLayout Orientation="Horizontal">
        <skia:SKCanvasView x:Name="skCanvasView" PaintSurface="skCanvasView_PaintSurface" HorizontalOptions="Fill" VerticalOptions="Fill">
            <skia:SKCanvasView.GestureRecognizers>
                <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped" />
            </skia:SKCanvasView.GestureRecognizers>
        </skia:SKCanvasView>
        <Button Text="Test"/>
    </StackLayout>
</ContentPage>
// MainPage.xaml.cs
using Microsoft.Maui.Controls;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Graphics.Skia;
using SkiaSharp;
using SkiaSharp.Views.Maui;
using SkiaSharp.Views.Maui.Controls;
using System.Diagnostics;

namespace TestSKCanvasView;

public partial class MainPage : ContentPage
{

    private Microsoft.Maui.Graphics.Color _fillColor = new Microsoft.Maui.Graphics.Color(0, 0, 255);

    public MainPage()
    {
        InitializeComponent();
    }

    private void skCanvasView_PaintSurface(object sender, SkiaSharp.Views.Maui.SKPaintSurfaceEventArgs e)
    {
        SKImageInfo info = e.Info;
        SKSurface surface = e.Surface;
        SKCanvas canvas = surface.Canvas;

        canvas.Clear();

        SKPaint paint = new SKPaint
        {
            Style = SKPaintStyle.Fill,
            Color = _fillColor.ToSKColor().WithAlpha(50)
        };

        var rect = new RectF(4.0f, 4.0f, Convert.ToSingle(Bounds.Width) - 3.0f, Convert.ToSingle(Bounds.Height) - 10f);

        canvas.DrawRoundRect(rect.X, rect.Y, rect.Width, rect.Height, 5.0f, 5.0f, paint);
    }

    private void TapGestureRecognizer_Tapped(object sender, TappedEventArgs e)
    {

    }
}

Expected Behavior It doesn't crash.

Actual Behavior It crashes.

Basic Information

Detailed IDE/OS information (click to expand) Windows 11 Pro Version 10.022621 .net7.0windows10.0.19041.0 ```

Screenshots

Reproduction Link

Dave-Quick commented 1 year ago

This works fine on Xamain.Forms.

I have an example project that includes the code you see here and would be happy to upload it here.

Dave-Quick commented 1 year ago

Just found the answer to my immediate problem.

In MauiProgram.cs add .UseSkiaSharp() to the builder like this:

builder

  .UseMauiApp<App>()
  .UseSkiaSharp(true)
  .ConfigureFonts(fonts => ... 

and add namespace 'SkiaSharp.Views.Maui.Controls.Hosting':

using SkiaSharp.Views.Maui.Controls.Hosting;

SkiaSharp needs this call.

Found it here: https://mapsui.com/documentation/getting-started-maui.html

Is this documented anywhere? The only thing I could find was this:( https://learn.microsoft.com/en-us/dotnet/api/skiasharp.views.maui.controls.hosting.apphostbuilderextensions.useskiasharp?view=skiasharp-views-maui-2.88) And that really doesn't tell me much.

I'm new to maui, but not new to Xamarin.Forms or SkiaSharp. I read this article (https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects?view=net-maui-7.0) and it didn't mention this.

It took me two days to track it down. If this work-around is the standard way to do it, it would be nice to have it documented somewhere that's easy to find.

I'll leave the bug open until I get a reply.