1

我想以编程方式将图像放入不活动的表单中。

Image myImage = new Image();
gfx = Form.ActiveForm.CreateGraphics();
gfx.DrawImage(myImage, 0,0);

只有当表单处于活动状态时它才会完美地工作,但是当表单不活动时它是没有意义的,只是返回一个错误:

在对象引用的实例中未设置为对象。

如何处理在我的应用程序中未激活的表单并为其添加图片?

更新 1

我做了实例,并打开了 DoubleBuffered 属性(true),但没有任何反应:

Form1 form = new Form1();
gfx = form.CreateGraphics();
gfx.DrawImage(bmp, 0, 0);

upd 2 More Source,这是我添加的课程

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Printing;

namespace testimg
{
    class doimg
    {

        public void picture()
        {

            // some staffs to get a picture, so it's in bmp object now.

            gfx = this. // watch picture below
            gfx.DrawImage(bmp, 0, 0);

            // I tried to use PictureBox, but it's the same issue (I can't handle it on a form)
            PictureBox pb = new PictureBox();
            pb.CreateGraphics();
            pb.DrawToBitmap(bmp,pb.ClientRectangle);

        }

    }
}

Arif Eqbal解决方案的图片:没有用于此的图形方法(图片)

更新3

我所拥有的完整来源(计时器在 10 秒)

Form1.cs

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 testimg
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {

            doimg pic = new doimg();

            pic.picture();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            timer1.Enabled = true;
        }
     }
}

doimg.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Printing;


namespace testimg
{
    class doimg
    {

        public void picture()
        {

            // some staffs to get a picture, so it's in bmp object now.
            Bitmap bmp = new Bitmap(200, 200,    System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            Graphics gfx = Graphics.FromImage(bmp);
            gfx = Form1.ActiveForm.CreateGraphics(); // works well with active form
            gfx.DrawImage(bmp, 0, 0);


        }


     }
}

以及项目http://www.filedropper.com/testimg的整个存档

正如您所看到的,在程序处于活动状态时一切运行良好。仍然需要帮助。

4

4 回答 4

2

在您的 Form2 上,尝试这样设置:

public partial class Form2 : Form {

  public Image MyImage { get; set; }

  public Form2() {
    InitializeComponent();
  }

  protected override void OnPaint(PaintEventArgs e) {
    if (MyImage != null) {
      e.Graphics.DrawImage(MyImage, 0, 0);
    }
    base.OnPaint(e);
  }
}

然后从您的活动表单中,您可以调用另一个表单来绘制自己:

public partial class Form1 : Form {
  Form2 f2 = new Form2();

  public Form1() {
    InitializeComponent();
    f2.Show();
  }

  private void button1_Click(object sender, EventArgs e) {
    f2.MyImage = myImage;
    f2.Invalidate();
  }
}
于 2012-07-26T02:37:04.560 回答
1

您必须创建表单的一个实例。无论它是否可见和活动。

例子:

Image myImage = new Image(); // load image
MyForm form = new MyForm();
gfx = form.CreateGraphics();
gfx.DrawImage(myImage, 0, 0);

然后,当您想要显示表单时,您将能够调用 form.Show()。

(注意,您可能还必须将表单上的 DoubleBackBuffer 设置为 true。

于 2012-07-26T02:01:21.693 回答
1

部分问题是,当您设置位图时,表单没有更新,特别是如果它被最小化或没有焦点。您还有一个问题,因为它没有在 Paint Event Handler 中设置,所以您没有保留图像。尝试这样的事情,注意Invalidate通话和计时器设置为 10,000 毫秒。如果您正在使用多种表单,这是@LarsTech 答案的变体,他是要走的路。

public partial class Form1 : Form
{
    Bitmap myImage;

    public Form1()
    {
        InitializeComponent();
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        myImage = new Bitmap("Your Image Name Here");
        Invalidate();

    }

    private void Form1_Paint(object sender, PaintEventArgs e)
    {

        if (myImage != null)
            e.Graphics.DrawImage(myImage,0,0);

    }


}

修改了我的示例以使用 OP 的结构:

当表单没有焦点时,我的原始示例确实有效。您的错误主要问题是Form1.ActiveForm在它不是活动表单时使用,它将返回导致您的错误的 null 。使用 Forms Paint 事件并使 Form 无效以确保 Image 被绘制。

Form1.cs

namespace testimg
{
    public partial class Form1 : Form
    {
        Bitmap myImage;

        public Form1()
        {
            InitializeComponent();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            myImage = doimg.picture();
            Invalidate();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            timer1.Enabled = true;
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            if (myImage != null)
                e.Graphics.DrawImage(myImage,0,0);
        }
    }
}

doimg.cs

namespace testimg
{
    static class  doimg
    {
        static Color[] clr = new Color[] { Color.Red, Color.Blue, Color.Black, Color.Violet, Color.Wheat };
        static  int count = 0;
        static  public Bitmap picture()
        {

            // some staffs to get a picture, so it's in bmp object now.
            Bitmap bmp = new Bitmap(200, 200, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            // Added some drawing to bitmap to test functionality
            Graphics gfx = Graphics.FromImage(bmp);
            gfx.FillEllipse(new SolidBrush(clr[count]),new Rectangle(0,0,199,199));

            gfx.Dispose();

            if (count >= 4)
                count = 0;
            else
                count += 1;

            return bmp;
        }
    }
}
于 2012-07-26T04:54:17.530 回答
0

我想我可以理解它......您的获取表单实例并在其上绘制的代码是否在计时器上运行?而你的申请只有一种形式?当应用程序不活动时,您会遇到问题吗?

如果是,则替换该行

Form.ActiveForm.CreateGraphics(); 

this.CreateGraphics(); 

Form.ActiveForm 为应用程序提供当前活动表单的引用,如果您在说单击按钮时编写此代码,您一定会获得单击按钮的表单的名称。但是,如果代码在计时器上,它可能会给出 Active 表单的实例,如果整个应用程序不是 Active,则可能会给出 Null。

正如您在其中一条评论中提到的,您没有任何其他表单,您的应用程序似乎只有一个表单,并且此代码在应用程序中的唯一表单上运行,因此 this.CreateGraphics 应该足够了。但是,如果您的应用程序有多个表单,那么 Form.ActiveForm 是合法代码,但您需要注意没有表单处于活动状态的情况,即应用程序本身不活动。

编辑:

我认为您需要将要在其上绘制的 Form 实例传递给此类。创建一个属性并将属性值设置为表单的实例,您也可以在构造函数中传递它......在这里使用 Form.ActiveForm 不是一个坏主意,但有两个原因,明天如果您有多个表单在您的应用程序中,它将随机绘制在任何一个处于活动状态的情况下,其次是在您当前的情况下,如果应用程序未处于活动状态,您将无法获取实例......因为您的应用程序中只有一个表单,我想您将创建表单上此类的实例,因此您可以添加一个属性

public Form ParentForm { get; set; }

在课堂上并将其设置为

myClassObject.ParentForm = this;

在您创建此类的实例时在表单上然后说

ParentForm.CreateGraphics

在课堂里

于 2012-07-26T03:32:18.333 回答