【C#】画像ファイルの数だけPictureBoxコントロールを生成して画像を表示させるには

この記事では、画像ファイルの数だけPictureBoxコントロールを生成して画像を表示させる方法についてご説明します。

【動画】画像ファイルの数だけPictureBoxコントロールを生成して画像を表示させる実際の動き

本題に入る前に、まずは次の動画をご覧ください。


dataGridViewにある画像ファイルのフルパスを元に、PictureBoxコントロールに画像が表示されます。

画像ファイルとdataGridViewの例

今回は以下の画像ファイルとdataGridViewを用意しました。

データテーブルから画像ファイルのフルパスを取得し、そのフルパスを元にPictureBoxに表示させます。

その画像ファイルを上記のフォルダに19枚格納してあります。

PictureBoxに19枚の画像を表示させた結果は下のとおりです。

コードの流れ

STEP.1
データテーブルから画像ファイルのフルパスを取得する
データテーブルから画像ファイルのフルパスを取得します。
STEP.2
PictureBoxを生成する
PictureBoxを生成します。
PictureBoxを生成する際、画像ファイルのフルパスやPictureBoxのサイズの設定値などを設定します。

C#のコード(例)

App.configのコード

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
    </startup>
    <appSettings>
        <!-- 接続文字列 -->
        <add key="DBConnString" value="Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}" />

        <!-- Accessのデータベースファイルのパス -->
        <add key="DBPath" value="C:\work\10_勉強\21_C#\0046\0046.mdb" />

    </appSettings>
</configuration>

注目すべきコード①

最初に見て頂きたいのは8行目と11行目です。

8行目は、Accessのデータベースファイルに接続するのに必要な接続文字列を「DBConnString」というキーに設定しているコードです。

11行目は、Accessのデータベースファイルのパスを「DBPath」というキーに設定しているコードです。

「DBConnString」と「DBPath」のキーの値をフォーム側のコードが参照して使います。

フォームのコード

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Data;
using System.Data.OleDb;
using System.Configuration;

namespace wfcs_0046
{
    public partial class Form1 : Form

    {   
        public Form1()
        {
            InitializeComponent();
        }

        void Form1_Load(object sender, EventArgs e)
        {
            // DataGridViewのデータソースをnullに設定して表示されているデータをクリアする
            dataGridView1.DataSource = null;

            // DataGridViewの列をクリアして表示されている列を削除する
            dataGridView1.Columns.Clear();

            // App.configのappSettingsタグ内に記述した「DBConnString」のキーの値を取得して変数「connStrTemplate」に格納する
            string connStrTemplate = ConfigurationManager.AppSettings["DBConnString"];

            // App.configのappSettingsタグ内に記述した「DBPath」のキーの値を取得して変数「dbPathStr」に格納する
            string dbPathStr = ConfigurationManager.AppSettings["DBPath"];

            // connStrTemplateの{0}の部分を、「dbPathStr」の値に置き換える
            string connectionString = string.Format(connStrTemplate, dbPathStr);

            // OleDbConnectionインスタンスを生成する
            using (OleDbConnection connection = new OleDbConnection(connectionString))
            {
                // Accessのデータベースファイルに接続する
                connection.Open();

                // SQLクエリを作成します
                string query = "SELECT * FROM t_pic";

                // OleDbCommandインスタンスを生成する
                using (OleDbCommand command = new OleDbCommand(query, connection))
                {
                    // OleDbDataAdapterインスタンスを生成する
                    using (OleDbDataAdapter adapter = new OleDbDataAdapter(command))
                    {
                        // DataTableインスタンスを生成する
                        DataTable dt = new DataTable();

                        // データテーブルにデータを格納する
                        adapter.Fill(dt);

                        // DataGridViewにデータを表示する
                        dataGridView1.DataSource = dt;

                        // PictureBoxの左位置を設定する。左位置はdataGridView1の幅に50を足した値(お好きな値で設定(調整)してください)
                        int xPos = dataGridView1.Width + 30;

                        // PictureBoxの上位置を設定する。上位置は12を設定(お好きな値で設定(調整)してください)
                        int yPos = 35;

                        // データテーブルのデータ件数分処理を繰り返すforeach文
                        foreach (DataRow row in dt.Rows)
                        {
                            // データテーブルから画像のフルパスを取得
                            string fullPath = row["ファイル"].ToString();

                            // 新しいPictureBoxを生成する
                            PictureBox picBox = new PictureBox();

                            // PictureBoxに画像を設定する
                            picBox.Image = Image.FromFile(fullPath);

                            // PictureBoxのSizeModeをStretchImageに設定する(StretchImageはPictureboxに表示を合わせる)
                            picBox.SizeMode = PictureBoxSizeMode.StretchImage;

                            // PictureBoxの位置を設定する
                            picBox.Location = new Point(xPos, yPos);

                            // PictureBoxをフォームに追加する
                            this.Controls.Add(picBox);

                            // 次のPictureBoxの位置を更新する(PictureBoxの位置を10離す)
                            xPos += picBox.Width + 10;
                            
                            if (xPos + picBox.Width > this.ClientSize.Width)
                            {
                                // 設置しようとするPictureBoxの位置とPictureBoxの幅を足した値が、クライアント領域(Controlが設置できる領域)を超えている場合
                                // (⇒次のPictureBoxを設置しようとするとはみ出てしまうので新しい行に移動する)

                                // PictureBoxの上位置を再設定する(PictureBoxの位置を10離す)
                                yPos += picBox.Height + 10;

                                // PictureBoxの左位置を設定する。左位置はdataGridView1の幅に50を足した値(お好きな値で設定(調整)してください) 
                                xPos = dataGridView1.Width + 30;
                            }
                        }
                    }
                }

                // Accessのデータベースファイルの接続を閉じる
                connection.Close();
            }

            // dataGridViewの全ての列を自動調整する
            dataGridView1.AutoResizeColumns();
        }
    }
}

注意

以上のコードは「Form1_Load」イベントプロシージャを使用しています。

この「Form1_Load」イベントプロシージャを呼び出すには「Form1_Load」イベントプロシージャをイベントに登録しないと実行されないので注意です。

以上のイベント登録をしておかないと「Form1_Load」イベントプロシージャが実行されないので忘れないように設定しておきましょう。

注目すべきコード①

最初に見て頂きたいのは4行目から6行目です。

using System.Data;
using System.Data.OleDb;
using System.Configuration;

4行目の「using System.Data」はDataTableクラスを扱うのに必要な名前空間です。

DataTableクラスからインスタンスを生成し、取得したAccessのテーブルデータを格納することができます。

5行目の「using System.Data」はOleDbConnectionクラスを使うのに必要な名前空間です。

OleDbConnectionクラスからインスタンスを生成し、OleDbConnectionインスタンスのOpenメソッドを実行することでAccessのデータベースに接続することができます。

6行目の「using System.Configuration」はConfigurationManagerクラスを使うのに必要な名前空間です。

ConfigurationManagerクラスからインスタンスを生成し、ConfigurationManagerのインスタンスのAppSettingsプロパティに「App.config」のキーを指定することで、「App.config」からキーの値を取得することができます。

例えば、以下の30行目のコードの場合、AppSettingsプロパティに「DBPath」を指定しています。

            string dbPathStr = ConfigurationManager.AppSettings["DBPath"];

この「DBPath」はApp.configの「DBPath」のキーを指します。

		

AppSettingsプロパティに「DBPath」を指定しているので、変数「dbPathStr」には「C:\work\10_勉強\21_C#\0046\0046.mdb”」が格納されます。

注目すべきコード②

次に見て頂きたいのは21行目から24行目です。

            // DataGridViewのデータソースをnullに設定して表示されているデータをクリアする
            dataGridView1.DataSource = null;

            // DataGridViewの列をクリアして表示されている列を削除する
            dataGridView1.Columns.Clear();

コードの説明

以上のコードは、datagridviewの表示をクリアする処理のコードです。

21行目でDataSourceにnullを設定することで表示されているデータをクリアし、24行目のClearメソッドを実行することで表示されている列を削除します。

以上の2行のコードを実行することでdatagridviewの表示がクリアされます。

注目すべきコード③

次に見て頂きたいのは27行目から30行目です。

            // App.configのappSettingsタグ内に記述した「DBConnString」のキーの値を取得して変数「connStrTemplate」に格納する
            string connStrTemplate = ConfigurationManager.AppSettings["DBConnString"];

            // App.configのappSettingsタグ内に記述した「DBPath」のキーの値を取得して変数「dbPathStr」に格納する
            string dbPathStr = ConfigurationManager.AppSettings["DBPath"];

コードの説明

以上のコードは、App.configのappSettingsタグ内に記述した「DBConnString」「DBPath」のキーの値を取得して変数に格納するコードです。

「DBConnString」のキーの値は変数「connStrTemplate」に、「DBPath」のキーの値は変数「dbPathStr」に格納します。

注目すべきコード④

次に見て頂きたいのは33行目です。

            // connStrTemplateの{0}の部分を、「dbPathStr」の値に置き換える
            string connectionString = string.Format(connStrTemplate, dbPathStr);

コードの説明

以上のコードは、connStrTemplateの{0}の部分を、「dbPathStr」の値に置き換える処理のコードです。

connStrTemplateの{0}の部分を、「dbPathStr」の値に置き換える、とはどういうことかというと、{0}の部分をAccessのデータベースファイルのフルパスに置き換える、ということです。

今回は接続文字列と、Accessのデータベースのフルパスを分けてそれぞれ「DBConnString」と「DBPath」とキーを分けてあるので、フォームのコード側で接続文字列と、Accessのデータベースのフルパスを一つの文字列に組み立てています。

参考までに、string.Format実行前と実行後の状態を以下にお見せします。

以上のように、{0}の部分が「C:\work\10_勉強\21_C#\0046\0046.mdb」に置き換わっています。

参考:string.Format実行前

Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}

参考:string.Format実行後

Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\work\10_勉強\21_C#\0046\0046.mdb

注目すべきコード⑤

次に見て頂きたいのは36行目から39行目です。

            // OleDbConnectionインスタンスを生成する
            using (OleDbConnection connection = new OleDbConnection(connectionString))
            {
                // Accessのデータベースファイルに接続する
                connection.Open();

コードの説明

以上のコードは、OleDbConnectionオブジェクトを作成し、Accessのデータベースファイル接続している処理のコードです。

コードの詳細

36行目のコードでは、App.configから取得したAccessのデータベースファイルの接続情報(connectionString)を元にOleDbConnectionインスタンスを作成しています。

39行目のコードでは、生成したOleDbConnectionインスタンスのOpenメソッドを実行してAccessのデータベースファイルに接続しています。

注目すべきコード⑥

次に見て頂きたいのは42行目から57行目です。

                // SQLクエリを作成します
                string query = "SELECT * FROM t_pic";

                // OleDbCommandインスタンスを生成する
                using (OleDbCommand command = new OleDbCommand(query, connection))
                {
                    // OleDbDataAdapterインスタンスを生成する
                    using (OleDbDataAdapter adapter = new OleDbDataAdapter(command))
                    {
                        // DataTableインスタンスを生成する
                        DataTable dt = new DataTable();

                        // データテーブルにデータを格納する
                        adapter.Fill(dt);

                        // DataGridViewにデータを表示する
                        dataGridView1.DataSource = dt;

コードの説明

以上のコードは、Accessのテーブルデータを取得するSELECT文を用意して実行し、取得したAccessのテーブルデータをdataGridViewに表示する処理のコードです。

コードの詳細

42行目のコードでは、Accessのテーブルデータを取得するSELECT文を用意しています。

45行目のコードでは、SELECT文を実行するために、SELECT文とOleDbConnectionインスタンス(connection)を指定してOleDbCommandクラスからインスタンスを生成します。

48行目のコードでは、OleDbDataAdapterインスタンスを生成し、SELECT文を関連付けます。

OleDbDataAdapterインスタンスが生成されたことで、SELECT文を実行することができるようになります。

51行目のコードでは、SELECT文を実行して取得したデータを格納するのに必要なDataTableのインスタンス「dt」を生成します。

54行目のコードでは、Fillメソッドを実行するとSELECT文が実行されて、取得したデータが「dt」に格納されます。

57行目のコードでは、取得したAccessのテーブルデータをdataGridViewに表示させます。

注目すべきコード⑦

次に見て頂きたいのは60行目から100行目です。

                        // PictureBoxの左位置を設定する。左位置はdataGridView1の幅に50を足した値(お好きな値で設定(調整)してください)
                        int xPos = dataGridView1.Width + 30;

                        // PictureBoxの上位置を設定する。上位置は12を設定(お好きな値で設定(調整)してください)
                        int yPos = 35;

                        // データテーブルのデータ件数分処理を繰り返すforeach文
                        foreach (DataRow row in dt.Rows)
                        {
                            // データテーブルから画像のフルパスを取得
                            string fullPath = row["ファイル"].ToString();

                            // 新しいPictureBoxを生成する
                            PictureBox picBox = new PictureBox();

                            // PictureBoxに画像を設定する
                            picBox.Image = Image.FromFile(fullPath);

                            // PictureBoxのSizeModeをStretchImageに設定する(StretchImageはPictureboxに表示を合わせる)
                            picBox.SizeMode = PictureBoxSizeMode.StretchImage;

                            // PictureBoxの位置を設定する
                            picBox.Location = new Point(xPos, yPos);

                            // PictureBoxをフォームに追加する
                            this.Controls.Add(picBox);

                            // 次のPictureBoxの位置を更新する(PictureBoxの位置を10離す)
                            xPos += picBox.Width + 10;
                            
                            if (xPos + picBox.Width > this.ClientSize.Width)
                            {
                                // 設置しようとするPictureBoxの位置とPictureBoxの幅を足した値が、クライアント領域(Controlが設置できる領域)を超えている場合
                                // (⇒次のPictureBoxを設置しようとするとはみ出てしまうので新しい行に移動する)

                                // PictureBoxの上位置を再設定する(PictureBoxの位置を10離す)
                                yPos += picBox.Height + 10;

                                // PictureBoxの左位置を設定する。左位置はdataGridView1の幅に50を足した値(お好きな値で設定(調整)してください) 
                                xPos = dataGridView1.Width + 30;
                            }
                        }

コードの説明

以上のコードは、データテーブルから画像ファイルのフルパスを取得し、そのフルパスを元にPictureBoxに表示させます。

コードの詳細

60行目と63行目でまずは1つ目のPictureBoxをどの位置に設置するかを決めます。

今回は60行目で左位置にdataGridView1の幅に50を足した値を、63行目で上位置に12を設定しています。(この値はお使いの環境に合わせて設定してください。)

以上の設定値で表示させた結果は下のとおりです。

65行目は、データテーブルのデータ件数分処理を繰り返すforeach文です。

Accessのテーブルから取得して格納したデータテーブル(dt)にあるデータの件数分、foreach文内で処理を繰り返します。

69行目では、データテーブルから画像のフルパスを取得します。

72行目では、新しいPictureBoxを生成します。

75行目では、PictureBoxに画像を設定します。

78行目では、PictureBoxのSizeModeをStretchImageに設定します。

今回は表示させたい画像をPictureBoxに合わせて伸縮させてPictureBox全体に埋めこみます

81行目では、60行目と63行目で取得したPictueBoxの横位置と縦位置の値をLocationプロパティに設定します。

84行目では、PictureBoxをフォームに追加します。

87行目では、次に生成したいPictureBoxの横位置を取得します。

生成したPictueBoxの次に生成したいPictueBoxは、右隣りに間隔を空けて設置したいので、今回は10の値を変数xPosに足しておきます。(この値はお使いの環境に合わせて設定してください。)

次に生成したPictueBoxは下のとおりに設置されます。

89行目は、PictureBoxを設置する位置がフォームからはみ出るかどうかを判定するIF文です。

はみ出るかどうかは、設置しようとするPictureBoxの位置とPictureBoxの幅を足した値が、クライアント領域を超えるかどうかで判断します。

クライアント領域とは、下の画像の通りです。

画像にある赤枠の中、つまりコントロールが設置できる範囲をクライアント領域と呼びます。

もしこのクライアント領域PictureBoxが超えてしまうとフォーム上からはみ出てしまい欠けて表示されてしまうため、その状態を避けるためにこの条件判定を行いチェックします。

もしクライアント領域PictureBoxが超えてしまうとフォーム上からはみ出てしまう場合は、95行目でPictureBoxの表示位置を下にずらすようPictureBoxの上位置を再設定します。

上位置を再設定することで、すでに設置したPictureBoxに重ならなくなります。

そして次に98行目で、1つ目に設置したPictureBoxと同じ横位置にPictureBoxを設置するようxPos の値を設定します。

表示位置を下にずらして表示させたPictureBoxは下のとおりです。

すでに設置されているPictureBoxの下にずらしてPictureBoxが設置されています。

注目すべきコード⑧

次に見て頂きたいのは105行目です。

                // Accessのデータベースファイルの接続を閉じる
                connection.Close();

コードの説明

以上のコードは、Accessのデータベースファイルの接続を閉じる処理のコードです。

注目すべきコード⑨

次に見て頂きたいのは108行目です。

            // dataGridViewの全ての列を自動調整する
            dataGridView1.AutoResizeColumns();

コードの説明

以上のコードは、dataGridViewの列幅を自動調整するコードです。

以下のように列の値が隠れて表示されてしまわないよう表示されるようAutoResizeColumnsメソッドを実行します。

動作確認

「画像ファイルとdataGridViewの例」をご覧ください。

【注意】参照設定が必要です

一つ注意点があるのですが、先ほどのコードを動かすには参照設定が必要です。

「System.Configuration」の項目を追加しないと、「ConfigurationManager」が存在しないとのことでエラーになってしまいます。

本コードを実行する際は、「System.Configuration」の項目を追加しましょう。

最後に

この記事では、画像ファイルの数だけPictureBoxコントロールを生成して画像を表示させる方法についてご説明しました。

画像ファイルの数だけPictureBoxコントロールを生成して画像を表示させたいときは本記事を参考にしてみてくださいね。

プログラミングのスキルを習得するなら

プログラミングのスキルを習得したい、今のスキルをもっと高めたい、そう考えているなら「プログラミングスクール」がおすすめです。

プログラミングのスキルの基礎を身につけるなら「TechAcademy」で1週間の無料体験があるので、これで「プログラミングの基礎」を学ぶのにおすすめですよ。

→ TechAcademyの「1週間 無料体験」はこちら