Formの上に、パネルをいくつか配置し、それぞれの上にコントロールやグラフィクス、イメージを表示したみた。
そもそもは、Dobon.netに記述されていたコード ”Panel1.Invalidate();” の意味が分からず、”Invalidate()”の前は、ふつう”this”じゃないの、、、と思いつつ、、、
数日悩んだあげく、やっと ”Invalidate()” の前には、再描画させたいパネル(領域)を指定するということに気が付いた。
というわけで、このソースには Invalidate() が2つ、Panelが3つ含まれている。
また、おかげでPenelの上に、コントロール、グラフィクス、イメージの表示のさせ方がわかった。
// https://dobon.net/vb/dotnet/graphics/creategraphics.html
// 高橋麻奈著 やさしいC# p211,222 SBCreative
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace Project1
{
class Class1 : Form
{
// 変数の宣言と代入
//画像ファイルを読み込む
Image[] images = new Image[] {
Image.FromFile(@"C:\materials\picture\car100_50.bmp"),
Image.FromFile(@"C:\materials\picture\racingcar100_50.bmp")
};
Image currentImage = null;
Image backImage = Image.FromFile(@"C:\materials\picture\thankful640_640.jpg");
// ラベルの宣言
Label lb0, lb1, lb2, lb3;
// フロアパネルの宣言
Panel panel1, panel2, panel3;
// ボタンの宣言
Button button1;
// パネル3の上でマウスクリックしたときに、その位置を記憶するリストの宣言
private List<Point> ls;
// メインメソッド
public static void Main()
{
Application.Run(new Class1());
}
// コンストラクタ
public Class1()
{
// ウインドウの定義
Text = "Panelをいくつか配置し、グラフィックス、コントロール、イメージを表示する";
Width = 640;
Height = 640;
//パネル3の上でマウスクリックしたときに、その位置を記憶するリスト
ls = new List<Point>();
// パネル1(領域1)の定義
panel1 = new Panel();
panel1.BorderStyle = BorderStyle.FixedSingle; //境界線
panel1.Location = new Point(300, 300);
panel1.Size = new Size(100, 100);
panel1.BackColor = Color.Gray;
this.Controls.Add(panel1);
// パネル2(領域3)の定義
panel2 = new Panel();
panel2.BorderStyle = BorderStyle.FixedSingle; //境界線
panel2.Location = new Point(100, 200);
panel2.Size = new Size(200, 100);
this.Controls.Add(panel2);
// パネル3(領域3)の定義
panel3 = new Panel();
panel3.BorderStyle = BorderStyle.FixedSingle; //境界線
panel3.Location = new Point(0, 400);
panel3.Size = new Size(300, 200);
this.Controls.Add(panel3);
// ボタン1の定義
button1 = new Button();
button1.Text = "ボディーカラー変更\nこの赤いボタンを押してください。";
button1.AutoSize = true;
button1.Dock = DockStyle.Bottom;
button1.BackColor = Color.Red;
panel2.Controls.Add(button1);
// ラベル0の定義
lb0 = new Label();
lb0.ForeColor = Color.Blue;
lb0.BackColor = Color.Yellow;
lb0.Text = "thisの領域";
this.Controls.Add(lb0);
// ラベル1の定義
lb1 = new Label();
lb1.Text = "panel1の領域";
panel1.Controls.Add(lb1);
// ラベル2の定義
lb2 = new Label();
lb2.Text = "panel2の領域";
panel2.Controls.Add(lb2);
// ラベル2の定義
lb3 = new Label();
lb3.AutoSize = true;
lb3.Text = "panel3の領域。\nこの領域でクリックしてください";
panel3.Controls.Add(lb3);
// 画像の初期化
currentImage = images[0];
//ボタン1のイベントハンドラの登録
button1.Click += new EventHandler(Button1_Click);
//Panel1_Paintで記述された内容を、Panel1に描画するためにイベントハンドラを登録する
this.Paint += new PaintEventHandler(Back_Paint);
//Panel1_Paintで記述された内容を、Panel1に描画するためにイベントハンドラを登録する
panel1.Paint += new PaintEventHandler(Panel1_Paint);
panel3.MouseDown += new MouseEventHandler(Panel3_MouseDown);
panel3.Paint += new PaintEventHandler(Panel3_Paint);
}
// Panel1のPaintイベントハンドラ
private void Panel1_Paint(Object sender, PaintEventArgs e)
{
if (currentImage != null)
{
// DrawImageメソッドで画像をpanel1の座標系の(0, 25)の位置に表示する
Graphics g = e.Graphics;
g.DrawImage(currentImage, 0, 25, currentImage.Width, currentImage.Height);
}
}
// thisのPaintイベントハンドラ
private void Back_Paint(Object sender, PaintEventArgs e)
{
if (backImage != null)
{
//DrawImageメソッドで画像を示する
Graphics g = e.Graphics;
g.DrawImage(backImage, 0, 0, backImage.Width, backImage.Height);
}
}
//Button1のClickイベントハンドラ
private void Button1_Click(object sender, EventArgs e)
{
//表示する画像を入れ替える
if (currentImage != images[0])
{
currentImage = images[0];
}
else
{
currentImage = images[1];
}
//コントロールを再描画する。これがないと、新しい画像が表示されない。
this.Invalidate();
panel1.Invalidate(); //panel1に対してのみ、グラフィックスをInvalidate()する。
}
// Panel3でマウスをクリック(ダウン)したときのイベントハンドラ
public void Panel3_MouseDown(Object sender, MouseEventArgs e)
{
Point p = new Point();
p.X = e.X;
p.Y = e.Y;
ls.Add(p);
panel3.Invalidate();
}
// Panel3で描画するためのイベントハンドラ
public void Panel3_Paint(Object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
Pen dp = new Pen(Color.Pink, 3);
foreach (Point p in ls)
{
g.DrawEllipse(dp, p.X - 5, p.Y - 5, 10, 10);
}
}
}
}
最後に
本記事を作成後4年余り過ぎて初めてストックされました。(感動)
しかし、久しぶりに見て驚き、この記事は20,000人もの人が閲覧してくださっている。驚きだ。しかし、20,000人もの人が見て、初めてのストックとはなんとも情けない。検索ワードとしては引っかかるのだが、内容が詰まらないのだろう。
さて、C#の勉強を続ければ、次のようなアプリが作れるようになります。
語学学習用アプリの開発(途中)
役に立たない定規をつくる
2024年10月6日追記