画像付きラベルを実現してみる
用途はともかく、テキストと画像がくっついた ように見える ラベルを作る方法を検討した。
諸般の事情でオーナードローなどの方法は、学んでる時間がとれないので検討から外す。
目標
テキストと画像を表示するラベル、をゴールに設定する。
- ラベルより大きな画像は適当な大きさに縮小できること。
- テキストと画像の位置を指定できること、ひとまず左右のみ。
- 長いテキストは折り返し表示して画像にかからない。
- ラベルには全体を囲う外枠 (Border) をつけられること。
実現方法
- できあがりサイズは、200 x 50 px、うち画像は 50 x 50 px とする。
- 画像は、プロジェクト (App.config が作られる) フォルダに適当な背景透明の png ファイルを置く。
設計時
実行時
その1: Label の上にそっと PictureBox を重ねる
できあがりサイズの Label を用意して、その右端に PictureBox を「置く」。
外枠線を実現するために、Label の内部に PictureBox が位置づけられるようにしている。
最初に思いつく方式、単純。移動は両コントロールの Location で制御。煩雑だが、初学者にも直感的に理解できる。背景色を指定する場合なども両コントロールの背景色を設定する必要がある。
ただし、この弱点は、ユーザーコントロールに閉じ込めてしまえば、利用側は気にする必要はなくなるかもしれない。
private void Form1_Load(object sender, EventArgs e)
{
// その1
label1.BackColor = SystemColors.ActiveCaption;
label1.Size = new Size(200, 50);
label1.Text = "label1label1label1label1label1label1label1label1";
label1.BorderStyle = BorderStyle.FixedSingle;
pictureBox1.Size = new Size(48, 48);
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBox1.BackColor = SystemColors.ActiveCaption;
pictureBox1.PictureBox = Image.FromFile("../../sample.png");
}
その2 Label を PictureBox の子コントロールとして配置する
Label を PictureBox の子コントロールにする。これも、素直な手。Padding プロパティを使って画像を右端に追いやる。
画像を左に置く場合は同じく Padding プロパティと、Label の Location で調整する。
PictureBox と Label だけで構成できるのが好感できる。
private void Form1_Load(object sender, EventArgs e)
{
// その2
label2.BackColor = Color.Transparent;
label2.Parent = pictureBox2;
label2.Location = Point.Empty;
label2.Size = new Size(148, 48);
label2.Text = "label2label2label2label2label2label2label2label2";
pictureBox2.BorderStyle = BorderStyle.FixedSingle;
pictureBox2.Size = new Size(200, 50);
pictureBox2.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBox2.BackColor = SystemColors.ActiveCaption;
pictureBox2.Padding = new Padding(150, 0, 0, 0);
pictureBox2.PictureBox = Image.FromFile("../../sample.png");
pictureBox2.Controls.Add(label2);
}
その3 !NG! Label に PictureBox と Text を設定する
「テキストが画像にかからない」という点で目標を満たせない。Padding プロパティがイメージとテキストの両方に効くので重なってしまう。
private void Form1_Load(object sender, EventArgs e)
{
// その3
var PictureBox = Image.FromFile("../../sample.png");
var canvas = new Bitmap(48, 48);
using (var g = Graphics.FromImage(canvas))
{
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.DrawImage(image, 0, 0, 48, 48);
image.Dispose();
}
label3.BorderStyle = BorderStyle.FixedSingle;
label3.Size = new Size(200, 50);
label3.PictureBox = canvas;
label3.TextAlign = ContentAlignment.TopLeft;
label3.ImageAlign = ContentAlignment.MiddleRight;
label3.BackColor = SystemColors.ActiveCaption;
label3.Text = "label3label3label3label3label3label3label3label3";
}
その4 レイアウトパネルに Label と PictureBox を配置する
もう少し複雑なレイアウト要求が出てきそうなら、FlowLayOutPanel や TableLayoutPanel などに配置した方がよくなるかもしれない。
private void Form1_Load(object sender, EventArgs e)
{
// その4
flowLayoutPanel4.BorderStyle = BorderStyle.FixedSingle;
flowLayoutPanel4.Size = new Size(200, 50);
flowLayoutPanel4.Controls.Add(label4);
flowLayoutPanel4.Controls.Add(pictureBox4);
flowLayoutPanel4.BackColor = SystemColors.ActiveCaption;
label4.BackColor = Color.Transparent;
label4.Size = new Size(148, 48);
label4.Text = "label4label4label4label4label4label4label4label4";
pictureBox4.Size = new Size(48, 48);
pictureBox4.BackColor = Color.Transparent;
pictureBox4.PictureBox = Image.FromFile("../../sample.png");
}
確認した環境
- OS: 日本語 Windows 10 Home 64ビット
- コンパイラ: Visual Studio Community 2017 RC