.NET的CustomLineCap构造函数引发NotImplementedException异常。

5

我想绘制一个自定义的线条端点 - 一个半径为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) 

我是不是做错了什么,还是只是框架的一个bug?

编辑:

在Mark Cidade的提醒下,我尝试使用(Nothing, path),它有所帮助,但我需要填充三角形,而不仅仅是描边...

4个回答

0
异常来自于GDI+库从其GdipCreateCustomLineCap()函数返回一个NotImplemented状态。尝试传递一个笔画路径而不是Nothing:
  Dim path2 As GraphicsPath = New GraphicsPath()
  path2.AddLines(points);
  _HlpCap = New CustomLineCap(path, path2) 

fillPathstrokePath参数不能同时使用。必须传递一个参数为null值。如果两个参数都不传递null值,则fillPath将被忽略。参考 - Wyck

0

显然,路径不能穿过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);

0
在我的情况下,我让帽子的分段长度取决于容器的宽度。每当我缩小窗体到一定限制时,我的程序总是停止并抛出异常。 后来我发现,当任何一个分段的长度达到1时,就会抛出异常。 因此,请确保您帽子路径中的所有分段长度都大于1。

0

不好

这是一个使用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轴。

文档中的备注非常重要:

fillPathstrokePath参数不能同时使用。一个参数必须传递一个null值。如果两个参数都没有传递null值,则fillPath将被忽略。如果strokePathnull,则fillPath应该与负y轴相交。

这是其中一种措辞不当的情况。文档说“应该相交”,但我认为它“必须相交”,否则你会得到一个System.NotImplementedException。这个相交问题仅适用于fillPath,而不是strokePath。(文档可能也需要一些图片。)

这是一个绘制箭头的GraphicsPath示例,它可以在线条末端正确地工作。这很可能是大多数人想要绘制的箭头。

enter image description here

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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接