- - PR -
フォーム表示時のピクチャボックス描画
1
投稿者 | 投稿内容 |
---|---|
|
投稿日時: 2008-07-17 15:25
非常に初歩的なところの質問でスミマセンが、どなたか教えてください。
フォームにピクチャボックス(picArea)を配置して、フォームロード時にこのピクチャボックスに四角を書きたいと考えています。以下のようなソースでやってみたのですが、四角を書いた直後に、四角が消えてしまいます。どこが悪いのでしょうか? public class MainForm : Form { System.Drawing.Graphics g; System.Drawing.Pen p; public MainForm() { g = picArea.CreateGraphics(); p = new Pen(Color.Blue, 1); } private void MainForm_Load(object sender, EventArgs e) { g.DrawRectangle(p, 10, 20, 100, 80); } } このソースだと、フォームの大きさを変えると四角が表示されます。 よろしくお願いします。 |
|
投稿日時: 2008-07-17 19:04
過去ログを探せば、描画関係のスレッドが幾つも見つかります。
似たような質問もあったはず・・・。 描画はOnPaintをオーバーライドして その中で描画しましょう。 画面の描画(再描画)が必要な時にはOnPaintが呼ばれます。 [追記] ぁ・・・。継承しないなら、Paintイベントにハンドラを登録して そのイベントハンドラ内で描画すれば良いかと。 [ メッセージ編集済み 編集者: くまっち 編集日時 2008-07-17 19:11 ] |
|
投稿日時: 2008-07-17 21:23
くまっちさん、ありがとうございます
OnPaintのオーバーライドを以下のように組み込んでみました。 public class MainForm : Form { System.Drawing.Graphics g; System.Drawing.Pen p; public MainForm() { g = picArea.CreateGraphics(); p = new Pen(Color.Blue, 1); } protected override void OnPaint(PaintEventArgs e) { p = new System.Drawing.Pen(System.Drawing.Color.Blue, 1); g.DrawRectangle(p, 10, 20, 100, 80); } } このコードを実行すると、OnPaintに処理が移ります。確かに何かを書こうとします。 興味深いのは最初にフォームに青い四角を描いて、そのあとにピクチャボックスを書いています。結果何も書いていないという状況に変わりはありませんでした。つまり 四角を描く→ピクチャボックス表示(結果何も書かれていない) というわけです。そもそもなぜ上記のような処理をするのかわかりません。ピクチャボックスに四角を描くのは ピクチャボックス表示→四角を描く となっているはずだと思っているのですが、何か根本的に間違っているのでしょうか? |
|
投稿日時: 2008-07-17 22:10
OnPaintイベントハンドラに引数である、e.Graphicsに描画を行ってみた?
|
|
投稿日時: 2008-07-17 22:12
私の書き方も、判りにくかったですね。
まず、FormとPictureBoxは各々描画(OnPaint呼出)されます。 Formが描画される際には、Formに含まれる子コントロール(PictureBox等)も 必要があれば描画されます。 つまり描画順を考慮しなければなりません。 Form.OnPaint その後に PictureBox.OnPaintなので FormのOnPaint段階では上書きされて消されてしまいます。 継承してオーバーライドというのは PictureBoxを継承してPictureBoxEx(継承したクラス)の OnPaintで描画するという事です。 で、継承が面倒(わざわざ派生クラスを作りたくない)ならば PictureBoxのPaintイベントにイベントハンドラを登録して そのイベントハンドラ内で描画すれば良いという事です。 |
|
投稿日時: 2008-07-17 22:32
ありがとうございます。
private void picArea_Paint(object sender, PaintEventArgs e) { // } にイベントハンドラを登録して、そのイベントハンドラ内に描画すればよいとのことですが・・・イベントハンドラをやったことがないので、もう少し教えていただけないでしょうか?? すみませんがよろしくお願いします。 |
|
投稿日時: 2008-07-17 22:36
OnPaint はリアルタイムで 10ms で全面書き換えとかゲームでも作らない限り
使わない方が良いです。 PictureBoxには前と後ろの画像データ領域が実装されています。要するに2つの 画像を重ね合わせ表示することが出来るようになっています。利用する側は 前か後ろどちらでもいいからPictureBoxと同じ大きさのBitmapを作成してそれを プロパティに設定するだけで表示に関する一切の処理はすべてPictureBoxが肩代 わりしてくれます。 OnPaint はどーしても処理が間に合わない場合にだけ実装するようにしましょう。 過去ログやMSDNにもサンプルがあるので見てください。 |
|
投稿日時: 2008-07-17 22:50
こんな感じでしょうか?
public class MainForm : Form { System.Drawing.Graphics g; System.Drawing.Pen p; public MainForm() { g = picArea.CreateGraphics(); p = new Pen(Color.Blue, 1); } private void MainForm_Load(object sender, EventArgs e) { MakeGraphics(); } private void MakeGraphics() { picArea.Image = new Bitmap(picArea.Width, picArea.Height); Graphics gfx = Graphics.FromImage(picArea.Image); p = new System.Drawing.Pen(System.Drawing.Color.Blue, 1); gfx.DrawRectangle(p, 10, 20, 100, 80); } } うまくいきました。動作速度も全く問題がありませんでした。 OnPaintについても、私は一つだろうと思っておりましたし、勉強になりました。 ありがとうございました。 |
1