持久图形 WinForms

2024-01-10

我有一个 WinForms 应用程序,我必须在控件之间画一些线。这些行需要持久存在,所以我覆盖了表单OnPaint() event.

问题是,重新绘制的线条不是很平滑。

我正在创建图形如下:

Graphics g;
g = this.CreateGraphics();
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.FillRectangle(Brushes.White, this.ClientRectangle);

并绘制线条如下:

public void lineDraw(Control L1, Control L2) {            
    using (Pen pen = new Pen(Color.Black, 4)) {
        pen.StartCap = System.Drawing.Drawing2D.LineCap.Flat;
        pen.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;
        int x1, x2, y1, y2;
        //choose x/y coordinates
        g.DrawLine(pen, x1, y1, x2, y2);
    }
}

我可以设置任何属性来提高绘制图形的平滑度吗?


Goal

图像显示在控件(或窗体)上。

无效

每当控件(或窗体)调整大小、最小化/最大化、部分模糊或移动时,都必须(部分)重绘。当发生这种情况时,必须重绘的控件部分被称为无效的.

当无效时,控件会执行以下操作:

  1. Call OnPaintBackground:这会用背景颜色填充无效区域。
  2. Call OnPaint:这会在背景之上绘制文本和图形。

Why OnPaint导致闪烁

你已经覆盖了OnPaint method http://msdn.microsoft.com/en-us/library/system.windows.forms.control.onpaint.aspx的控制。每次重新绘制控件时,您都会看到控件的闪烁,其中仅绘制了其背景颜色。那是之后OnPaintBackground已被调用并且之前OnPaint已被调用。

解决方案

  • 如果您有静态图像(即它永远不会改变):

    1. In the Load事件:创建一个新的Bitmap object http://msdn.microsoft.com/en-us/library/system.drawing.bitmap.aspx.
    2. 用背景颜色填充它并在上面绘制线条和形状。
    3. 分配这个Bitmap反对控制BackgroundImage财产 http://msdn.microsoft.com/en-us/library/system.windows.forms.control.backgroundimage.aspx.
  • 如果您有一个静态图像,必须在控件调整大小时调整其大小:

    1. 覆盖OnResize method http://msdn.microsoft.com/en-us/library/system.windows.forms.control.onresize.aspx并创建新的Bitmap在那里。使用控件的ClientSize财产 http://msdn.microsoft.com/en-us/library/system.windows.forms.control.clientsize.aspx对于尺寸Bitmap.
    2. 用背景颜色填充它并在上面绘制线条和形状。
    3. 分配这个Bitmap反对控制BackgroundImage财产。
  • 如果您有动画图像:

    1. In the Load事件设置了DoubleBuffered财产 http://msdn.microsoft.com/en-us/library/system.windows.forms.control.doublebuffered.aspx的控制到true。设置此项可以防止您看到的闪烁,因为它使用不可见的缓冲区来绘制控件。
    2. 覆盖控件的OnPaint method http://msdn.microsoft.com/en-us/library/system.windows.forms.control.onpaint.aspx。获取Graphics context http://msdn.microsoft.com/en-us/library/system.drawing.graphics.aspx并直接在控件上绘制线条和形状。
    3. 创建并启用新的Timer object http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx并在其回调方法中调用控件的Invalidate method http://msdn.microsoft.com/en-us/library/598t492a.aspx接下来是Update method http://msdn.microsoft.com/en-us/library/system.windows.forms.control.update.aspx (如图所示 https://stackoverflow.com/a/2695790/146622)。将计时器设置为每 40 毫秒触发一次。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

持久图形 WinForms 的相关文章

  • 将处理后的图形绘制到另一个图形中

    我想将一个经过处理的图形绘制到另一个图形中 I have two graphics var gHead Graphics FromImage h var gBackground Graphics FromImage b Transform
  • 在 OpenCL 中将函数作为参数传递

    是否可以在 OpenCL 1 2 中将函数指针传递给内核 我知道可以用C实现 但不知道如何在OpenCL的C中实现 编辑 我想做这篇文章中描述的同样的事情 在 C 中如何将函数作为参数传递 https stackoverflow com q
  • 通信对象 System.ServiceModel.Channels.ServiceChannel 不能用于通信

    通信对象System ServiceModel Channels ServiceChannel 无法用于通信 因为它处于故障状态 这个错误到底是什么意思 我该如何解决它 您收到此错误是因为您让服务器端发生 NET 异常 并且您没有捕获并处理
  • 处理 fanart.tv Web 服务响应 JSON 和 C#

    我正在尝试使用 fanart tv Webservice API 但有几个问题 我正在使用 Json Net Newtonsoft Json 并通过其他 Web 服务将 JSON 响应直接反序列化为 C 对象 这里的问题是元素名称正在更改
  • 在 C++11 中省略返回类型

    我最近发现自己在 C 11 模式下的 gcc 4 5 中使用了以下宏 define RETURN x gt decltype x return x 并编写这样的函数 template
  • TextBox 焦点的 WinForms 事件?

    我想添加一个偶数TextBox当它有焦点时 我知道我可以用一个简单的方法来做到这一点textbox1 Focus并检查布尔值 但我不想那样做 我想这样做 this tGID Focus new System EventHandler thi
  • 如何在 VS 中键入时显示方法的完整文档?

    标题非常具有描述性 是否有任何扩展可以让我看到我正在输入的方法的完整文档 我想查看文档 因为我可以在对象浏览器中看到它 其中包含参数的描述和所有内容 而不仅仅是一些 摘要 当然可以选择查看所有覆盖 它可能是智能感知的一部分 或者我不知道它并
  • VS30063:您无权访问 https://dev.azure.com

    我正在尝试在 asp net core 2 1 mvc 应用程序中使用以下代码连接 Azure DevOps Uri orgUrl new Uri https dev azure com xxxxx String personalAcces
  • C++11 函数局部静态 const 对象的线程安全初始化

    这个问题已在 C 98 上下文中提出 并在该上下文中得到回答 但没有明确说明有关 C 11 的内容 const some type create const thingy lock my lock some mutex static con
  • 如何用 kevent() 替换 select() 以获得更高的性能?

    来自Kqueue 维基百科页面 http en wikipedia org wiki Kqueue Kqueue 在内核和用户空间之间提供高效的输入和输出事件管道 因此 可以修改事件过滤器以及接收待处理事件 同时每次主事件循环迭代仅使用对
  • 是否有与 C++11 emplace/emplace_back 函数类似的 C# 函数?

    从 C 11 开始 可以写类似的东西 include
  • 范围和临时初始化列表

    我试图将我认为是纯右值的内容传递到范围适配器闭包对象中 除非我将名称绑定到初始值设定项列表并使其成为左值 否则它不会编译 这里发生了什么 include
  • 事件日志写入错误

    很简单 我想向事件日志写入一些内容 protected override void OnStop TODO Add code here to perform any tear down necessary to stop your serv
  • C# 创建数组的数组

    我正在尝试创建一个将使用重复数据的数组数组 如下所示 int list1 new int 4 1 2 3 4 int list2 new int 4 5 6 7 8 int list3 new int 4 1 3 2 1 int list4
  • C# 编译器如何决定发出可重定向的程序集引用?

    NET Compact Framework 引入了可重定向程序集引用 现在用于支持可移植类库 基本上 编译器会发出以下 MSIL assembly extern retargetable mscorlib publickeytoken 7C
  • 在 C 中复制两个相邻字节的最快方法是什么?

    好吧 让我们从最明显的解决方案开始 memcpy Ptr const char a b 2 调用库函数的开销相当大 编译器有时不会优化它 我不会依赖编译器优化 但即使 GCC 很聪明 如果我将程序移植到带有垃圾编译器的更奇特的平台上 我也不
  • 32位PPC rlwinm指令

    我在理解上有点困难rlwinmPPC 汇编指令 旋转左字立即然后与掩码 我正在尝试反转函数的这一部分 rlwinm r3 r3 0 28 28 我已经知道什么了r3 is r3在本例中是一个 4 字节整数 但我不确定这条指令到底是什么rlw
  • 是否有一个 C++ 库可以从 PDF 文件中提取文本,例如 PDFBox for Java? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 去年 我使用 PDFBox 在 Java 中创建了一个应用程序来获取某些 PDF 文件中的原始文本 现在
  • gdb查找行号的内存地址

    假设我已将 gdb 附加到一个进程 并且在其内存布局中有一个文件和行号 我想要其内存地址 如何获取文件x中第n行的内存地址 这是在 Linux x86 上 gdb info line test c 56 Line 56 of test c
  • 如何在 GCC 5 中处理双 ABI?

    我尝试了解如何克服 GCC 5 中引入的双重 ABI 的问题 但是 我没能做到 这是一个重现错误的非常简单的示例 我使用的GCC版本是5 2 如您所见 我的主要函数 在 main cpp 文件中 非常简单 main cpp include

随机推荐