System.NotSupportedException:'无法从本机句柄激活SkiaSharp.Views.Forms.SKCanvasViewRenderer类型的实例'

时间:2020-08-12 06:41:09

标签: xamarin xamarin.forms skiasharp

我正在尝试通过触摸替换ContentView.Content。 但是,如果我触摸ContentView,则会遇到一个奇怪的异常,如下所示。

System.NotSupportedException:'无法从本机句柄激活SkiaSharp.Views.Forms.SKCanvasViewRenderer类型的实例'

复制过程

  1. 创建空白Xamarin项目。
  2. 添加“ MyContetView.cs”文件。
  3. 复制并粘贴源代码
    public class MyContentView : ContentView
    {
        private string _text;
        private SKCanvasView _canvasView;
        private Editor _editorView;

        public MyContentView()
        {
            _text = "Hello, World!";

            _canvasView = new SKCanvasView()
            {
                WidthRequest = 100,
                HeightRequest = 100,
                EnableTouchEvents = true
            };
            _canvasView.PaintSurface += (sender, e) =>
            {
                e.Surface.Canvas.Clear();

                var rect = new SKRect(0, 0, 
                    (float)(Width * Xamarin.Essentials.DeviceDisplay.MainDisplayInfo.Density), 
                    (float)(Height * Xamarin.Essentials.DeviceDisplay.MainDisplayInfo.Density));
                var rectPaint = new SKPaint()
                {
                    Color = SKColors.Red,
                    IsStroke = false,
                    StrokeWidth = 1
                };
                e.Surface.Canvas.DrawRect(rect, rectPaint);

                var textPaint = new SKPaint()
                {
                    Color = SKColors.Black,
                    IsAntialias = true,
                    TextSize = 16
                };
                e.Surface.Canvas.DrawText(_text, 0, 0, textPaint);
            };
            _canvasView.Touch += (sender, e) =>
            {
                ToggleContent();
                e.Handled = true;
            };

            _editorView = new Editor()
            {
                AutoSize = EditorAutoSizeOption.TextChanges
            };

            _editorView.Completed += (sender, e) =>
            {
                _text = _editorView.Text;
            };
            _editorView.Unfocused += (sender, e) =>
            {
                ToggleContent();
            };

            _canvasView.InvalidateSurface();
            Content = _canvasView;
        }

        public void ToggleContent()
        {
            if (Content == _canvasView)
            {
                Content = _editorView;
            }
            else
            {
                _canvasView.InvalidateSurface();
                Content = _canvasView;
            }
        }
    }
  1. 运行
  2. 触摸

Github

2020.08.13更新

我在 Xamarin.Forms 上创建了一个issue,因为替换ContentView.Content应该有效,因为SKCanvasView像其他 Xamarin一样继承了View .Froms

解决方法

代替替换ContentView.Content,在VisualElement.IsVisibleSKCanvasView之间切换Editor

<ContentView.Content>
    <AbsoluteLayout>
        <skia:SKCanvasView x:Name="CanvasView"
                                          AbsoluteLayout.LayoutFlags="All"
                                          AbsoluteLayout.LayoutBounds="0, 0, 1, 1"
                                          IsVisible="True" 
                                          EnableTouchEvents="True"/>
        <Editor x:Name="EditorView"
                     AbsoluteLayout.LayoutFlags="All"
                     AbsoluteLayout.LayoutBounds="0, 0, 1, 1"
                     IsVisible="False"
                     AutoSize="TextChanges" />
    </AbsoluteLayout>
</ContentView.Content>
public void ToggleState()
{
            if (isCanvasView)
            {
                CanvasView.IsVisible = true;
                CanvasView.Focus();

                EditorView.IsVisible = false;
                EditorView.Unfocus();
            }
            else
            {
                CanvasView.IsVisible = false;
                CanvasView.Unfocus();

                EditorView.IsVisible = true;
                EditorView.Focus();
            }
}

对于更简洁的代码,与if相比,状态模式可能是一个很好的解决方案。

0 个答案:

没有答案
相关问题