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

时间:2012-07-26 01:48:34

标签: c# winforms

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

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);

更新 2更多来源,这是我添加的课程

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 解决方案的图片:no graph methods for this (pic)

更新 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 个答案:

答案 0 :(得分: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();
  }
}

答案 1 :(得分:1)

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

示例:

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

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

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

答案 2 :(得分:1)

部分问题在于,当您设置位图时,表单不会更新,特别是如果它已最小化或没有焦点。您还遇到的问题是,由于未在Paint Event Handler中设置,因此您没有保留Image。尝试这样的事情,注意Invalidate调用,并将Timer设置为10,000 ms。如果你正在使用多种表格,这是@ 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,这会导致您的错误。使用“表单绘制事件”和“使表单无效”以确保图像已绘制。

<强> 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;
        }
    }
}

答案 3 :(得分:0)

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

如果是,则替换

Form.ActiveForm.CreateGraphics(); 

this.CreateGraphics(); 

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

正如您在其中一条评论中提到的,您没有任何其他表单,看来您的应用程序只有一个表单,而且此代码在应用程序中的唯一表单上运行,因此this.CreateGraphics就足够了。但是,如果您的应用程序有多个表单,则Form.ActiveForm是合法代码,但是当没有表单处于活动状态时,您需要处理该情形,即应用程序本身不活动。

编辑:

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

public Form ParentForm { get; set; }
在课堂上

并将其设为

myClassObject.ParentForm = this;
当您创建此类的实例然后说

时,在表单上

ParentForm.CreateGraphics

在班级