1

プログラムでアクティブでないフォームに画像を入れたいです。

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

フォームがアクティブな場合にのみ完全に機能しますが、フォームがアクティブでない場合は意味がなく、エラーが返されます。

オブジェクトに設定されていないオブジェクト参照のインスタンス。

私のアプリケーションでアクティブでないフォームを処理し、それに画像を配置する方法は?

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

        }

    }
}

ArifEqbalソリューションの写真:このためのグラフメソッドはありません(写真)

upd 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

問題の一部は、ビットマップを設定しているときにフォームが更新されないことです。特に、最小化されているか、フォーカスがない場合です。また、ペイント イベント ハンドラで設定されていないため、イメージが保持されないという問題もあります。このようなことを試してみてください。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が返され、エラーが発生します。フォーム ペイント イベントを使用し、フォームを無効にして、イメージが確実にペイントされるようにします。

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

私はそれを理解できると思います...フォームのインスタンスを取得してそれを描画するコードがタイマーで実行されるということですか? そして、あなたの申請書は 1 つのフォームしかありませんか? アプリケーションがアクティブでないときに問題が発生しますか?

はいの場合、行を置き換えます

Form.ActiveForm.CreateGraphics(); 

this.CreateGraphics(); 

Form.ActiveForm は、アプリケーションの現在アクティブなフォームの参照を提供します。たとえば、ボタンのクリック時にこのコードを記述すると、ボタンがクリックされたフォームの名前を取得する必要があります。ただし、コードがタイマー上にある場合、アプリケーション全体がアクティブでない場合は、アクティブ フォームまたは Null のインスタンスを与える可能性があります。

コメントの 1 つで他のフォームがないことを述べたように、アプリケーションにはフォームが 1 つしかなく、このコードはアプリ内の唯一のフォームで実行されているように見えるため、this.CreateGraphics で十分です。ただし、アプリケーションに複数のフォームがある場合、 Form.ActiveForm は正当なコードですが、アクティブなフォームがない場合、つまりアプリケーション自体がアクティブでない場合のシナリオに注意する必要があります。

編集:

描画したい Form のインスタンスをこのクラスに渡す必要があると思います。プロパティを作成し、プロパティ値をフォームのインスタンスに設定します。コンストラクターにも渡すことができます... Form.ActiveForm を使用することは、ここでは悪い考えではありませんでしたが、2 つの理由から、明日、複数のフォームがある場合あなたのアプリでは、アクティブな方にランダムに描画されます.2つ目は、現在のケースのように、アプリがアクティブでない場合、インスタンスを取得できません...アプリにはフォームが1つしかないため、作成していると思いますフォーム上のこのクラスのインスタンスなので、プロパティを追加できる場合があります

public Form ParentForm { get; set; }

クラスで、次のように設定します

myClassObject.ParentForm = this;

このクラスのインスタンスを作成し、次に言うときにフォーム上で

ParentForm.CreateGraphics

クラスで

于 2012-07-26T03:32:18.333 に答える