C#绘画处理程序中的绘图问题 [英] C# Problem with drawing in Paint handler

查看:227
本文介绍了C#绘画处理程序中的绘图问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在我的C#Windows Form应用程序中使用DrawString.在程序启动时,将触发三个绘画事件.在第一个事件中,字符串将以正确的位置写在表单上.在第二次和第三次绘画事件中,字符串写在正确位置的上方和左侧.

之后,程序将按预期运行. (先最小然后再最大,或者重新调整表单大小,然后正确绘制屏幕.)

DrawLine,DrawRectangle等会发生这种情况.

这是C#的错误,还是我很明显地遗漏了一些东西?这是整个应用程序.感谢您的帮助.

I am trying to use DrawString in my C# Windows Form application. On program startup, three paint events are fired. On the first event, the string is written on the form in the correct position. On the 2nd and 3rd paint events, the string is written above and to the left of the correct position.

After that, the program runs as expected. (Min and then max, or resize the form and the screen is drawn correctly.)

This happens with DrawLine, DrawRectangle, etc.

Is this a bug with C# or am I missing something VERY obvious? Here''s the WHOLE application. Thanks for any help you can give.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Junk
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            System.Drawing.Graphics graphicsObj;
            graphicsObj = this.CreateGraphics();
            Font myFont = new System.Drawing.Font("Helvetica", 40,                  FontStyle.Italic);
            Brush myBrush = new SolidBrush(System.Drawing.Color.Red);
            graphicsObj.DrawString("Hello C#", myFont, myBrush, 30, 100);
        }
    }
}

推荐答案

这不是整个应用程序.您如何知道Form1_Paint是添加到事件Paint的调用列表中的处理程序.依靠设计师?在许多情况下,Designer只会使开发变慢.

您已经有了Form类,为什么还要处理该事件?只是覆盖OnPaint会做完全相同的事情.现在,错误在哪里?这是使用其构造函数创建System.Drawing.Graphics实例的过程.您应该使用已经在PaintOnPaint的处理程序方法中传递给您的实例.它在事件参数parameter中传递.

更多错误:FontBrush未处理,因此您将有永久性的非托管资源泄漏.这很重要,因此它也应该处理可能的异常.通常,它是使用try-finally完成的,但是等效行为是使用using语句实现的(不要与using子句混淆,请参阅http://msdn.microsoft.com/en-us/library/yh598w02.aspx [
This is not a whole application. How do you know that Form1_Paint is a handler added to an invocation list of the event Paint. Relying on the Designer? There are many cases when the Designer only makes development slower.

As you already have your Form class, why handling the event at all? Just overriding OnPaint does exact same thing. Now, where is the mistake? This is creation of the instance of System.Drawing.Graphics using its constructor. You should use the instance which is already passed to you in the handler method of Paint or OnPaint; it is passed in event arguments parameter.

More mistakes: Font and Brush are not disposed, so you will have a permanent unmanaged resource leak. This is important enough, so it should also handle possible exceptions. Normally, it is done using try-finally, but the equivalent behavior is achieved using using statement (not to by confused with using clause, see http://msdn.microsoft.com/en-us/library/yh598w02.aspx[^]).

Also, there is not need to create a solid brush of an well-known color.

After all fixes:
protected override void OnPaint(PaintEventArgs eventArgs) {
    using (Font myFont = new System.Drawing.Font("Helvetica", 40, FontStyle.Italic)) {
        e.Graphics.DrawString("Hello C#", myFont, System.Drawing.Brushes.Red, 30, 100);
    } //myFont is automatically disposed here, even if an exception was thrown
}



如果需要移动图形并更改OnPaint使用的数据,则需要调用Control.Invalidate.您可以尝试使用带有参数(RegionRectange)的Control.Invalidate来仅刷新场景的一部分来提高性能.

另请参阅我过去的答案:
Paint是一种哪种好玩的方法? (DataGridViewImageCell.Paint(...)) [在mdi子窗体之间画线 [在面板上捕获图形 [如何从旧图纸中清除面板 [ ^ ](这有助于防止常见的PictureBox滥用).

—SA



If you need graphics to move, and change data used by OnPaint, you need to call Control.Invalidate. You can try to improve performance using Control.Invalidate with parameters (Region or Rectange) to refresh only the part of the scene.

See also my past answers:
What kind of playful method is Paint? (DataGridViewImageCell.Paint(...))[^],
Drawing Lines between mdi child forms[^],
capture the drawing on a panel[^],
How do I clear a panel from old drawing[^] (this one helps to prevent the very common abuse of PictureBox).

—SA


这篇关于C#绘画处理程序中的绘图问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆