【问题标题】:How to make a line drawn by graphics selectable in .NET如何在.NET中使由图形绘制的线可选择
【发布时间】:2013-06-25 01:10:02
【问题描述】:

绘制线条的简单代码。

using (Graphics g = this.CreateGraphics())
        {
            g.DrawLine(Pens.Black, new Point(50, 50), new Point(100, 100));
        }

这将绘制一条典型的线。但是我希望这条线是可选择的,以便用户可以在运行时进一步操作它(拉伸、调整大小等)。最初我尝试使用可以在运行时以线条作为背景进行操作的控件,但是由于控件重叠问题而无法工作。

我的问题是如何在运行时选择这一行?

【问题讨论】:

  • 您尝试使用哪些控件来操作线条?
  • 这个问题很笼统,没有准确的答案。你应该看看图形操作。我认为你必须想出一个独特的解决方案来解决你的问题。
  • 您也可以绘制一个平面多边形,而不是一条线,然后当您的鼠标单击位于“平面多边形内部”时,图形操作选项可以让您“访问该线”。有一些这样的功能。
  • @call2voyage 图片框,我可以在运行时让用户调整大小,但结果并不令人满意
  • @RomanoZumbé 我希望不要实施自定义解决方案,但看来我还是要感谢。

标签: c# .net graphics


【解决方案1】:

你需要自己写。

  1. 编写一个包装 Line 的类
  2. 向类添加所有需要的附加行为(选择线时会发生什么,拉伸、删除、更改颜色时会发生什么...)
  3. 编写一个类来管理对象是否被鼠标选中 (RayTracer)

等等……

或者干脆使用:piccolo2d 框架

结构化二维图形框架

【讨论】:

  • 如果这个问题很愚蠢,我很抱歉,但我对此真的很陌生,而且我没有完全遵循“换行的课程”。一个类如何换行?
  • @WinCoder: 具有在 Graphics 上画线的 Draw 方法的类,remove 方法,Stratch,GetLength 等等......也许你最好看看 Piccolo2D 框架,它是如何管理线条的.
【解决方案2】:

也许为时已晚,因为您已经接受了答案,但您真的应该为此考虑 WPF。

https://stackoverflow.com/a/15469477/643085

这是您在 WPF + MVVM 中所追求的精确示例。与任何 winforms 方法相比具有真正的全部优势(例如由于硬件加速而不会闪烁)。

请至少试一试。提供完整的 CSProj 项目源。

您真的在重新设计自己在 GDI 中实现这一切的轮子。最后它会因为闪烁和类似的东西而无法使用。

【讨论】:

  • 非常感谢您的建议朋友永远不会太迟:)。我听说 WPF 有一个陡峭的学习曲线,我想快速完成我的这个应用程序。你是对的,会有闪烁,但首先我必须完成这个项目。我不明白的一件事是人们一直说我在重新发明轮子,我不明白我的意思是它不像这样可选的行是内置在 winforms 中的
  • @WinCoder 你说的对我来说听起来很矛盾。 WPF 确实有一个陡峭的学习曲线,但是如果您想快速完成您的项目,只需获取我的代码并对其进行修改以满足您的需求。 winforms 不会帮你快速完成这个,因为它不支持你需要的基础设施。
  • @WinCoder 我是说您重新发明轮子,因为您基本上是在尝试构建 WPF 已有的功能,但 winforms 没有。这没有意义,微软已经为你做到了。而且我确信他们可以比我们任何人做得更好。
  • @WinCoder 只是看了那篇文章,我意识到我没有在任何地方发布完整的代码,所以here it is。您可能还想看看我的其他类似示例123
  • 确实你是对的,我确实听起来很矛盾:)。我想说我希望项目尽快结束,如果我开始学习 WPF 将需要更多时间,因为首先我必须得到从 WPF 开始(但它是我的个人项目,没有截止日期),因为我正在学习,我也更喜欢使用我自己的代码。确切地说,我正在尝试克隆 UMLet link
【解决方案3】:

您必须自己创建它。声明图形对象实现的接口。建议:

public interface IObject
{
    bool HitTest(Point mouseLocation);
    void Paint(Graphics g);
    List<IAdorner> Adorners { get; }
}

public interface IAdorner
{
    bool HitTest(Point mouseLocation);
    void Paint(Graphics g);

    void StartMoving(Point mouseLocation);
    void Move(Point mouseLocation);
}

例如,装饰器是线条对象的可选端点。

您的主要绘画程序将如下所示:

private void drawingSurface_Paintobject sender, PaintEventArgs e)
{
    foreach (IObject o in _objects) {
        o.Paint(e.Graphics);
        if (o == _selectedObject) {
            foreach (IAdorner a in o.Adorners) {
                a.Paint(e.Graphics);
            }
        }
    }
}

当然你需要所有的鼠标事件处理。

这些接口足够抽象,可以实现任何形状。例如,它们不包含任何坐标,因为不同类型的对象需要不同数量和种类的坐标和参数。

【讨论】:

  • 定义一个接口很好,但困难的部分是弄清楚HitTest是如何工作的。
【解决方案4】:

我认为您要做的是使 Graphics 对象可选择? 如果是这样,您可以将您的逻辑放入 MouseOver 和 MouseButton 事件中。 看看这个,它可能会给你一些见解。

Selectable Graphics Object

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-26
    • 1970-01-01
    • 2011-08-26
    • 2018-04-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多