简体   繁体   English

在新表格上绘制图形

[英]Draw graphics on new form

I am facing a problem on drawing graphics, pardon me as I am totally new to it. 我在绘制图形时遇到问题,请原谅我,这是我的新手。 What I have now, is a form named FormDraw. 我现在拥有的是一个名为FormDraw的表单。 In FormDraw, I have a button. 在FormDraw中,我有一个按钮。 what the button does is 该按钮的作用是

private void button1_Click(object sender, EventArgs e)
{
    using (Form form = new Form())
    {
        form.Text = "About Us";
        System.Drawing.Graphics graphics = this.CreateGraphics();
        System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle(100, 100, 200, 200);
        graphics.DrawEllipse(System.Drawing.Pens.Black, rectangle);
        graphics.DrawRectangle(System.Drawing.Pens.Red, rectangle);
        // form.Controls.Add(...);

        form.ShowDialog();
    }
}

What I am trying to achieve is draw the graphics on the new form, however upon clicking on the button it creates on the old form (FormDraw). 我想要实现的是在新表单上绘制图形,但是单击它会在旧表单(FormDraw)上创建的按钮上。 Any idea what am I doing wrong? 知道我在做什么错吗?

The main problem here seems to be that you haven't researched how drawing in the Winforms API works and so you're trying to use the API without understanding it. 这里的主要问题似乎是您尚未研究Winforms API中的绘图方式,因此您在不了解API的情况下尝试使用该API。 :( :(

The code you posted will attempt to draw just once into the newly created form object. 您发布的代码将尝试只绘制一次到新创建的form对象中。 This drawing is unlikely to work at all, since the rest of the form initialization hasn't completed yet, but even if something did draw to the screen, it would immediately be lost as new things are later drawn to the screen (like the form itself when it's finally shown). 由于其余的表单初始化尚未完成,因此该绘图根本无法工作,但是即使在屏幕上绘制了某些内容,当稍后将新内容绘制到屏幕上时,它也会立即丢失(例如表单)最终显示出来时本身)。

Winforms is, like most mainstream GUI APIs (including Mac OS, Java's SWT, AWT, Swing, etc. and of course the native Windows API) an "immediate mode" API. 与大多数主流GUI API(包括Mac OS,Java的SWT,AWT,Swing等,当然还有本机Windows API)一样,Winforms是“即时模式” API。 That is, your code is expected to draw on demand, and to draw what needs to be presented at that moment. 就是说,您的代码应按需使用,并在此刻需要显示的内容。 The API does not remember anything you've drawn; 该API不会记住您绘制的任何内容。 any time something happens (to your data or on the screen itself, such as window overlap changes) that would invalidate what you've already drawn, you have to draw it again. 每当发生任何事情(对您的数据或在屏幕本身上,例如窗口重叠更改)使您已经绘制的内容无效时,您都必须再次绘制它。

The only appropriate place to draw into a Winforms control (including a form) is when handling the Paint event, either in an actual handler or by overriding OnPaint() . 绘制Winforms控件(包括窗体)的唯一合适位置是在实际的处理程序中或通过重写OnPaint()处理Paint事件时。 If you want to execute drawing statements once, then you have to draw into a bitmap object (effectively caching them), and then draw the bitmap itself during the Paint event. 如果要一次执行绘图语句,则必须先绘制一个位图对象(有效地缓存它们),然后在Paint事件中绘制位图本身。

There's not enough context in your question to really be able to understand exactly what you're trying to do. 您的问题中没有足够的上下文来真正能够准确了解您要执行的操作。 But the code you posted can be fixed to work as (I think) you expect, by modifying it to look like this: 但是,通过将其修改为如下所示,可以将发布的代码固定为按您期望的方式工作(我认为):

private void button1_Click(object sender, EventArgs e) {
    using (Form form = new Form())
    {
        form.Text = "About Us";
        form.Paint += (sender, e) =>
        {
            System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle(100, 100, 200, 200);
            e.Graphics.DrawEllipse(System.Drawing.Pens.Black, rectangle);
            e.Graphics.DrawRectangle(System.Drawing.Pens.Red, rectangle);
        }

        // form.Controls.Add(...);

        form.ShowDialog();
    }
}

The PaintEventArgs class, passed to the handler of a Paint event, includes a Graphics property that is the Graphics instance that you are to use when drawing during the Paint event. 传递给Paint事件的处理程序的PaintEventArgs类包含一个Graphics属性, 属性是在Paint事件期间进行Paint时要使用 Graphics实例。

The above subscribes an anonymous event handler method to the new form's Paint event. 上面的方法为新表单的Paint事件订阅了一个匿名事件处理程序方法。 In that handler, your desired drawing is done using the Graphics instance provided to you via the PaintEventArgs passed to the handler. 在该处理程序中,使用所需的Graphics通过传递给该处理程序的PaintEventArgs提供给您的Graphics实例完成。

(Note that the above only fixes the Paint handling. Of course, you will need to otherwise correctly initialize the form object, such as setting its width and height, actually adding desired controls etc.) (请注意,以上内容仅修复了Paint处理。当然,您将需要正确地初始化表单对象,例如设置其宽度和高度,实际添加所需的控件等。)

You can use 'PictureBox' to show created image on new form. 您可以使用“ PictureBox”在新表单上显示创建的图像。

private void Button1_Click(object sender, EventArgs e)
    {
        // create Form instance
        Form form = new Form
        {
            Text = "About Us",
            Width = 440,
            Height = 460,
        };

        // create bmp image
        Bitmap bmp = new Bitmap(400, 400);
        // draw on bmp image
        using (Graphics graphics = Graphics.FromImage(bmp))
        {
            graphics.Clear(Color.Transparent);
            Rectangle rectangle = new Rectangle(100, 100, 200, 200);
            graphics.DrawEllipse(Pens.Black, rectangle);
            graphics.DrawRectangle(Pens.Red, rectangle);

        }
        // create PictureBox instance
        PictureBox pictureBox = new PictureBox
        {
            Image = bmp,
            //BorderStyle = BorderStyle.FixedSingle,
            //Dock = DockStyle.Fill,
            /// To center
            Size = new Size(400,400),
            Location = new Point(10,10)
        };
        // add pictureBox control to form
        form.Controls.Add(pictureBox);
        // show form in dialog box
        form.ShowDialog();
    }

Instead of using the above method i have posted in the question, i manage to do it using 我没有使用我在问题中发布的上述方法,而是设法使用

Form form2 = new Form();
form2.Show();

var graphics = form2.CreateGraphics();
var rectangle = new System.Drawing.Rectangle(100, 100, 200, 200);

graphics.DrawEllipse(System.Drawing.Pens.Black, rectangle);
graphics.DrawRectangle(System.Drawing.Pens.Red, rectangle);

however, i will do more research on the drawing class. 但是,我将在绘画课上做更多的研究。 thank you Peter Duniho 谢谢彼得·杜尼奥

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM