【问题标题】:NotImplementedException from .NET's CustomLineCap constructorNotImplementedException 来自 .NET 的 CustomLineCap 构造函数
【发布时间】:2010-08-03 09:30:17
【问题描述】:

我想绘制一个自定义线帽 - 一个半径为 r 的等边三角形。显然我不能:

  Dim triangleSide As Single = CSng(3 * r / Math.Sqrt(3))
  Dim triangleHeight As Single = CSng(3 * r / 2)
  path = New GraphicsPath()
  Dim points() As PointF = New PointF() { _ 
      New PointF(-triangleSide / 2, 0), _ 
      New PointF(triangleSide / 2, 0), _
      New PointF(0, triangleHeight) }
  path.AddLines(points)

  ' Not Implemented Exception, Was is Das? '
  _HlpCap = New CustomLineCap(path, Nothing) 

我有什么问题还是只是一个框架错误?

编辑:

在 Mark Cidade 发言之后,我尝试使用 (Nothing, path) 并有所帮助,但我需要填充三角形,而不仅仅是将其描出......

【问题讨论】:

    标签: .net gdi+ system.drawing notimplementedexception


    【解决方案1】:

    异常来自 GDI+ 库,它从其 GdipCreateCustomLineCap() 函数返回 NotImplemented 状态。尝试传递笔划路径而不是Nothing

      Dim path2 As GraphicsPath = New GraphicsPath()
      path2.AddLines(points);
      _HlpCap = New CustomLineCap(path, path2) 
    

    【讨论】:

    • fillPathstrokePath 参数不能同时使用。一个参数必须传递一个空值。如果两个参数都没有传递空值,fillPath 将被忽略。 reference
    【解决方案2】:

    显然,路径不能穿过 x 轴。我用这段代码创建了一个箭头帽:

      GraphicsPath capPath = new GraphicsPath();
      float arrowSize = 2.0f;
      capPath.AddLines(new PointF[] {
        new PointF(arrowSize, -(float)Math.Sqrt(3.0) * arrowSize),
        new PointF(0.0f, -0.01f),
        new PointF(-arrowSize, -(float)Math.Sqrt(3.0) * arrowSize)
      });
    
      CustomLineCap arrowCap = new CustomLineCap(capPath, null, LineCap.NoAnchor, (float)Math.Sqrt(3.0) * arrowSize);
    

    【讨论】:

      【解决方案3】:

      不好

      这是一个 GraphicsPath 的示例,它试图在行尾之外绘制一个箭头并导致 System.NotImplementedException

      GraphicsPath capPath = new GraphicsPath();
      capPath.AddLine(0, 8, -5, 0);
      capPath.AddLine(-5, 0, 5, 0);
      arrowPen.CustomEndCap = new CustomLineCap(capPath, null); // System.NotImplementedException
      

      这会失败,因为路径必须与负 Y 轴相交。但上面的路径只经过原点,实际上并没有碰到负 Y 轴。

      remarks in the docs 至关重要:

      fillPathstrokePath 参数不能同时使用。一个参数必须传递一个空值。如果两个参数都没有传递空值,fillPath 将被忽略。如果strokePathnullfillPath 应该截取负 y 轴。

      这是措辞不佳的情况之一。文档说“应该拦截”,但我认为这是“必须拦截”的情况,否则你会得到System.NotImplementedException。此拦截问题仅适用于fillPath,不适用于strokePath。 (文档也可能使用一些图片。)

      这是一个GraphicsPath 的示例,它在行尾绘制了一个箭头并且可以正常工作。它很可能是大多数人无论如何都想画的那种箭头。

      GraphicsPath capPath = new GraphicsPath();
      capPath.AddLine(0, 0, -5, -8);
      capPath.AddLine(-5, -8, 5, -8);
      arrowPen.CustomEndCap = new CustomLineCap(capPath, null); // OK
      

      修正你的例子

      解决方法是从 y 中减去 triangleHeight。这会将箭头的尖端放置在 0,0(这是线末端的坐标),这很可能是您想要的,并将三角形的底部放置在 -triangleHeight

      float radius = 5.0f;
      float triangleSide = 3.0f * radius / (float)Math.Sqrt(3.0f);
      float triangleHeight = 3.0f * radius / 2.0f;
      GraphicsPath capPath = new GraphicsPath();
      capPath.AddLines(new PointF[] {
          new PointF(-triangleSide / 2.0f, -triangleHeight),
          new PointF(triangleSide / 2.0f, -triangleHeight),
          new PointF(0, 0) }
      );
      arrowPen.CustomEndCap = new CustomLineCap(capPath, null);
      

      为您提供的确切解决方法(在 Visual Basic 中):

        Dim points() As PointF = New PointF() { _ 
            New PointF(-triangleSide / 2, -triangleHeight), _ 
            New PointF(triangleSide / 2, -triangleHeight), _
            New PointF(0, 0) }
        path.AddLines(points)
      

      【讨论】:

        【解决方案4】:

        在我的例子中,我已经让 cap 的段的长度取决于容器的宽度。每当我将表单缩小到一定限制时,我的程序总是会异常停止。 然后我发现当任何段的长度达到1时抛出异常。 因此,请确保上限路径中的所有段的长度都大于 1。

        【讨论】:

          猜你喜欢
          • 2016-10-07
          • 2014-02-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-08-16
          • 2012-07-28
          • 1970-01-01
          相关资源
          最近更新 更多