.NET的CustomLineCap构造函数中的NotImplementedException

时间:2010-08-03 09:30:17

标签: .net gdi+ system.drawing notimplementedexception

我想绘制一个自定义线帽 - 半径为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)并且它有所帮助,但我需要填写三角形,而不仅仅是为了抚摸它......

4 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

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

答案 2 :(得分: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轴。

remarks in the docs非常重要:

fillPathstrokePath参数不能同时使用。必须为一个参数传递一个空值。如果两个参数都未传递空值,则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)

答案 3 :(得分:0)

在我的情况下,我已将瓶盖段的长度取决于容器的宽度。每当我将表单缩小到一定限制后,我的程序总是会异常停止。 然后我发现任何段的长度达到1时都会引发异常。 因此,请确保帽形路径中的所有线段的长度都大于1。