久々の投稿です。
ここ最近はWindowsクライアントアプリ開発ばかりやってます。
今回のは自分用のメモです。
Panelの中にPictureBoxを整列させるだけですが、並べる数を可変にしています。 単純に自動配置するだけならFlowLayoutPanelクラスを使えばよさそうですが、 表示数を固定にしたかったので、自作しました。
環境
- Windows 10 Home
- Visual Studio 2015 Community
- C# WinForms
- .NET Framework 4.5.2
仕様
- Panel内に縦横に指定した数のPictureBoxを動的に並べる
- リサイズには対応しない
ソースコード
PictureBoxの個数と大きさから余白を計算して、描画する座標を計算しています。
余白計算ででた端数は両端の余白に追加しています。
そうしないと、左寄りになります。
/// <summary> /// Panel内に指定した枚数を並べる /// </summary> /// <param name="columnNum">縦に並べる個数</param> /// <param name="rowNum">横に並べる個数</param> private void setPictures(int columnNum, int rowNum) { // pictureboxのサイズ Size picSize = new Size(100, 80); // はみ出さないかチェック if (picSize.Width * rowNum > this.panel1.Width || picSize.Height * columnNum > this.panel1.Height) { return; } int offsetX, offsetY; // 調整用 int paddingX = calcPadding(picSize.Width, this.panel1.Width, rowNum, out offsetX); int paddingY = calcPadding(picSize.Height, this.panel1.Height, columnNum, out offsetY); // 左上の始点 Point startPos = new Point(paddingX + offsetX, paddingY + offsetY); Point nextPos = startPos; int count = columnNum * rowNum; this.SuspendLayout(); for (int i = 0; i < count; i++) { PictureBox pic = new PictureBox(); pic.BackColor = Color.Coral; pic.Size = picSize; pic.Location = nextPos; this.panel1.Controls.Add(pic); nextPos = calcNextPostion(startPos, nextPos, picSize, this.panel1.Width, paddingX, paddingY); } this.ResumeLayout(false); } /// <summary> /// 次の開始位置を計算 /// </summary> /// <param name="startPos">行の開始位置</param> /// <param name="lastPos">1つ前のPictureBocの座標</param> /// <param name="picSize">PictureBoxのサイズ</param> /// <param name="panelWidth">Panelの幅</param> /// <param name="paddingX">X軸方向の余白</param> /// <param name="paddingY">Y軸方向の余白</param> /// <returns></returns> private Point calcNextPostion(Point startPos, Point lastPos, Size picSize, int panelWidth, int paddingX, int paddingY) { Point newPos = new Point { X = lastPos.X + picSize.Width + paddingX, Y = lastPos.Y }; // 現在の行に収まるか bool isNextRow = panelWidth < newPos.X + picSize.Width + paddingX; if (isNextRow) { newPos.X = startPos.X; newPos.Y += picSize.Height + paddingY; } return newPos; } /// <summary> /// 余白計算 /// </summary> /// <param name="picSize">個体の長さ</param> /// <param name="rowSize">列の長さ</param> /// <param name="picNumInRow">1列に並べるPictureBoxの個数</param> /// <param name="offset">微調整用補正値</param> /// <returns></returns> private int calcPadding(int picSize, int rowSize, int picNumInRow, out int offset) { // 余白の合計 int totalPadding = rowSize - picSize * picNumInRow; // PictureBox間の余白 int padding = totalPadding / (picNumInRow + 1); // 端数の調整 double amari = totalPadding % (picNumInRow + 1); offset = Convert.ToInt32(Math.Round(amari / 2)); return padding; }
結果
こんな感じになりました。
カウントアップ時にPanel内のコントロールをすべて削除してから、setPicturesメソッドを読んで再描画しています。
ちょっと気持ちいい。