首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C#:在SKCanvas绘图时的AccessViolationException

C#:在SKCanvas绘图时的AccessViolationException
EN

Stack Overflow用户
提问于 2017-04-06 19:41:39
回答 1查看 1.3K关注 0票数 1

引言

我正在创建我的第一个Xamarin应用程序(它将首先针对UWP,然后是安卓,最后可能是iOS)。

基本上,应用程序应该检测到多个手指和圆圈会弹出每一个手指并跟随它们。

问题所在

当我试图从System.AccessViolationExceptiononPanning方法上画一个平淡无奇的SKCanvas时,我有一个MR.gestures

屏幕截图

详细信息

我是例外,System.AccessViolationException是最好的产品 HResult=0x80004003 Message=Attempted来读取或写入受保护的内存。这通常表明其他内存已损坏。 SkiaSharp.SkiaApi.sk_canvas_draw_circle(IntPtr t,单cx,单cy,单半径,IntPtr涂料)àSkiaSharp.SKCanvas.DrawCircle(单cx,单cy,单半径,SKPaint涂料) App1.MainPage.drawCircleOnCanvas(Point pointerPos,Int32 radius) dans d:\Profiles\qpollet\Documents\Visual 2017\Projects\App1\MainPage.xaml.cs:Lenge70àApp1.MainPage.onPanning(对象发送者,( dans e) dans d:\Profiles\qpollet\ PanEventArgs \Visual 2017\Projects\App1\MainPage.xaml.cs :ligne 54àPanEventArgsàXamarin.Forms.Platform.UWP.WindowsBasePlatformServices.<>c__DisplayClass2_0.b__0()

密码

MainPage.xaml.cs

代码语言:javascript
复制
using SkiaSharp;
using SkiaSharp.Views.Forms;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using MR.Gestures;

namespace App1
{
    public partial class MainPage : Xamarin.Forms.ContentPage
    {
        private static SKCanvas canvas;

        public MainPage()
        {
            InitializeComponent();
        }

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

            Point pointerPos = new Point
            {
                X = 200,
                Y = 400
            };
            drawCircleOnCanvas(pointerPos, 50);

            Point pointerPos1 = new Point
            {
                X = 1000,
                Y = 600
            };
            drawCircleOnCanvas(pointerPos1, 50);
        }

        private void onPanning(object sender, PanEventArgs e)
        {
            Debug.WriteLine("MR Panning !!!!!");

            try
            {
                List<Point> touches = e.Touches.ToList();
                //foreach (Point touch in touches)
                for(int i = 0; i <= touches.Count; i++)
                {
                    Point touch = touches[i];
                    Debug.WriteLine("index " + i + " : " + touch.X + " " + touch.Y);
                    drawCircleOnCanvas(touch, 50);
                }
            }
            catch (ArgumentNullException) { }
        }

        internal void drawCircleOnCanvas(Point pointerPos, int radius)
        {
            Debug.WriteLine(pointerPos.X + " " + pointerPos.Y);

            SKPaint circleFill = new SKPaint
            {
                IsAntialias = true,
                Style = SKPaintStyle.Fill,
                Color = SKColors.Red
            };
            canvas.DrawCircle(((float) pointerPos.X - radius), ((float) pointerPos.Y - radius), radius, circleFill);
        }
    }
}

MainPage.xaml

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:App1"
             xmlns:views="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms"
             xmlns:mr="clr-namespace:MR.Gestures;assembly=MR.Gestures"
             x:Class="App1.MainPage">

    <Label Text="Ooooh, you touch my tralala" 
           VerticalOptions="Center" 
           HorizontalOptions="Center" />

    <RelativeLayout>

        <mr:AbsoluteLayout
            RelativeLayout.XConstraint="{ConstraintExpression Type=Constant, Constant=0}"
            RelativeLayout.YConstraint="{ConstraintExpression Type=Constant, Constant=0}"
            RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width}"
            RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height}"

            BackgroundColor="Blue"

            x:Name="touchLayout"
            Panning="onPanning">

        </mr:AbsoluteLayout>

        <views:SKCanvasView
            RelativeLayout.XConstraint="{ConstraintExpression Type=Constant, Constant=0}"
            RelativeLayout.YConstraint="{ConstraintExpression Type=Constant, Constant=0}"
            RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width}"
            RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height}"

            PaintSurface="OnPainting"/>

    </RelativeLayout>
</ContentPage>

结果

知道吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-04-07 17:42:45

您将得到该错误,因为您正在保存画布。画布是在每个框架渲染上重新创建的,因此您不能保留它的句柄。

正确的方法是只在画布方法中引用画布。然后,在填充方法中,使用InvalidateSurface使曲面失效。

这将触发重绘,然后可以在新位置绘制项目。

代码语言:javascript
复制
class MainPage {
    List<Point> touches;
    void onPan() {
        touches = GetTouchPoints();
        view.InvalidateSurface();
    }
    void onPaint() {
        var canvas = ...;
        canvas.Draw(...);
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43264393

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档