【问题标题】:Xamarin / C# extending an existing classXamarin / C# 扩展现有类
【发布时间】:2020-02-05 08:32:38
【问题描述】:

我最近一直在学习 C# MVVM,但显然我没有掌握一些关于扩展类的知识......

在下面的示例中,SkiaSharp 是一个 Xamarin 矢量图形包,我已经获得了一些矢量图标,我希望有一个可重用的类来在应用程序的各个点对它们进行缩放和着色

我想如果我将“SKCanvasView”子类化,那么我可以传入变量(图标、颜色)——当代码在相关视图中时一切正常,但我希望它在共享代码中,所以我像这样引用它

         <ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:d="http://xamarin.com/schemas/2014/forms/design"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         mc:Ignorable="d"
         xmlns:local="clr-namespace:Custom"
         x:Class="NavigationIcons">

        <local:RenderSVG StyleId="F9001A"
                         Grid.Row="0"
                         Grid.Column="1"
                         HorizontalOptions="CenterAndExpand"
                         VerticalOptions="CenterAndExpand"
                         ClassId="vector.svg" 
                         PaintSurface="OnCanvasViewPaintSurface">

        </local:RenderSVG>

它构建了,但随后它抱怨“PaintSurface”的方法不在视图代码隐藏文件中,如果它引用另一个类,我当然认为不需要它

我会假设"local:SVGRender" 意味着所有代码都将从该共享类运行,而不是从 XAML 视图后面的类文件运行,但似乎不是?

public class RenderSVG : SKCanvasView
{


    void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
    {
        try
        { 
            // rendering code is here

        }
    }

}

抛出的错误是“EventHandler”Custom.RenderSVG.OnCanvasViewPaintSurface“在类型“NavigationIcons”中找不到正确的签名,所以它甚至没有尝试查看我创建的派生类

【问题讨论】:

  • PaintSurface 是一个事件,当您像上面所做的那样处理事件时,它基本上会创建一个事件处理程序,该事件处理程序将在该事件发生时处理该事件。所以基本上这就是你上面的代码似乎在做的事情,根据我对你的问题的理解,你不希望你想要的是在你分配一些东西时绘制你的图像。所以请给我们更多关于 RendeSvg 类的信息。
  • 它是如何开始绘图的?您是否使用ClassId 属性为其分配一个值,如果该属性更改为是,您是否调用所需的方法来绘制此图像?
  • 您是否尝试使用override 覆盖事件/方法?
  • OK 所有的道歉都不够清楚。当方法位于视图的代码中时,将调用 PaintSurface 事件。所以代码工作正常(这就是我没有包含它的原因)。但它“不存在”,因此当我在外部类(RenderSVG)中引用它时构建失败。我想知道 OnCanvasViewPaintSurface 方法的路径是否需要绝对路径?

标签: c# xamarin.forms


【解决方案1】:

正如@FreakyAli 所说,PaintSurface 是一个事件。在ContentView 中使用SKCanvasView 时,您将事件绑定到容器的方法(事件处理程序)。 SKCanvasView 将触发事件并调用容器方法。

但是,当您继承 SKCanvasView 时,您必须覆盖 OnPaintSurface。或者,您可以在某些时候通过代码将OnCanvasViewPaintSurface 事件处理程序附加到PaintSurface 事件(例如在构造时),并且在某些时候您还需要将其分离(在销毁之前)。覆盖OnPaintSurface 是首选方式。例如:

public class RenderSVG : SKCanvasView
{
    protected override void OnPaintSurface(SKPaintSurfaceEventArgs args)
    {
        try
        { 
            // rendering code is here
        }
    }
}

当然,您需要从 XAML 文件中删除 PaintSurface="OnCanvasViewPaintSurface"

<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
     xmlns:d="http://xamarin.com/schemas/2014/forms/design"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     mc:Ignorable="d"
     xmlns:local="clr-namespace:Custom"
     x:Class="NavigationIcons">

    <local:RenderSVG StyleId="F9001A"
                     Grid.Row="0"
                     Grid.Column="1"
                     HorizontalOptions="CenterAndExpand"
                     VerticalOptions="CenterAndExpand"
                     ClassId="vector.svg">
    </local:RenderSVG>

【讨论】:

  • 如前所述,我想我知道如何做后者,因为我现在使用 ViewModels 相当广泛,但是我试图尽可能多地理解 c#,所以我真的很想尝试让覆盖工作。你能给我一个例子,说明在这种情况下它可能会是什么样子吗?抛出的错误是“EventHandler”Custom.RenderSVG.OnCanvasViewPaintSurface“在类型“NavigationIcons”中找不到正确的签名,所以它甚至没有尝试查看我制作的派生类
  • 所以我做了一些阅读,发现一个 SO 帖子说你需要使用虚拟而不是覆盖,因为我在使用覆盖时遇到错误。但是,仍然存在上面指出的构建错误,其中 XAML 编译器失败,说后面的视图代码不包含该方法 - 就像它仍然在错误的地方寻找一样
  • 更新了我的答案。简而言之,OnPaintSurface 已经是 virtual 所以你只需在你的(后代)类中覆盖它
  • 呸,好吧,我不明白我怎么能简单地删除该引用(“PaintSurface”)并期待任何结果,但它现在部分工作!我现在缺少的一点是确定如何获取 SKSufaceView 的实际实例以接收 ClassID 和 StyleID?在 OnCanvasViewPaintSurface 中它是从发件人投射的,我如何在 OnPaintSurface 中得到相同的结果?到目前为止,感谢您的帮助!
  • 没关系,我明白你在构造函数中将 OnCanvasPaint 方法附​​加到 PaintSurface 的意思,效果很好。感谢负载
猜你喜欢
  • 1970-01-01
  • 2016-10-24
  • 2012-03-10
  • 2012-05-03
  • 2021-11-03
  • 1970-01-01
  • 1970-01-01
  • 2010-12-17
  • 1970-01-01
相关资源
最近更新 更多