LoginSignup
icoke
@icoke

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

pictureBox の配列

c#のフォームアプリケーションで PictureBox を配列として扱いたい
出来れば、.cs[デザイン]の方で設定してしまいたい

最近C#フォームアプリケーションの勉強を始めました。
今 vs2022 で反射神経を測るゲームを作ろうとしています。
そこで pictureBox を縦横 (4,4) 計16個用意し、timer で一定時間毎にランダムな pictureBox をオン(pictureBoxを指定色で塗りつぶし、ストップウォッチを起動した状態) にし、オンになった pictureBox がクリックされたらストップウォッチの時間を合計反応時間に加算して停止、制限時間後に平均反応時間を算出して表示しようとしています。
これを作るにあたり、作った pictureBox0 から pictureBox15 を扱う際、いちいちswitch文で16個の分岐を作ると冗長で分かりづらいので、これを pictureBox[16] のような配列にして

pictureBox[i].Image = onBmp
// onBmpは指定色で塗りつぶしたBitmap

などのようにして様々な処理したいです。
しかし .cs[デザイン] の方では pictureBox の配列を作る項目が見つからず、ネットで調べてみてもしっくりくる記事が見当たらず、これをどうしようか悩んでいます。

そこで質問です。

Q1.
 .cs[デザイン] で pictureBox の配列を作る方法はあるのか。

Q2.
 Q1 が出来ないならソースコードの方に記述して pictureBox の配列を作れるのか。
(追記)自己解決しました。普通にPictureBox[] pictureBoxs = new pictureBoxs[16]; で宣言したら使えるみたいですね。

(追記)質問追加します。
Q2.1.
Q2ができる場合、ソースコードの方で宣言した pictureBox の配列を .cs[デザイン]の方でいじる方法はあるか。

Q3.
 Q2 が出来るなら、.cs[デザイン]の方で用意した pictureBox[0] ~ pictureBox[15] に pictureBox0 ~ pictureBox15 を代入して

int* ints[10]
int int0 = 0;
// 1 ~ 8
int int9 = 9;

ints[0] = &int0;
// 1 ~ 8
ints[9] = &int9;

for ( int i = 0; i < 10; i++ ) {
    printf(" %d", int[i]);
}
// 実行結果
// 0 1 2 3 4 5 6 7 8 9

というcのアドレスを使ったような実装方法は可能なのか。

Q4.
 Q3が不可能な場合、考えられる中で一番スマートな実装方法を教えていただきたいです。

質問内容としては以上です。お答えいただければ幸いです。よろしくお願いいたします。

ソースコード

以下のソースコードは実装途中です。
Startボタンを押したらTimerが起動する代わりに、Box0がオンになります。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;

namespace reflexGame {
    public partial class Form1 : Form {
        // PictureBox[] pictureBoxes = new PictureBox[16];

        Bitmap onBmp, offBmp;

        Random rand = new Random();

        Box[] box = new Box[16];

        TimeSpan sum = TimeSpan.Zero;
        public Form1 ( ) {
            InitializeComponent();

            for ( int i = 0; i < 16; i++ ) {
                box[i] = new Box();
                // pictureBoxes[i] = new PictureBox();
            }
        }

        private void Form1_Load ( object sender, EventArgs e ) {
        }

        private void button1_Click ( object sender, EventArgs e ) {
            //timer1.Enabled = true;
            box[0].on(Box0);
        }

        private void Box0_Click ( object sender, EventArgs e ) {
            sum += box[0].off(Box0);
            aveTime2.Text = sum.ToString();
        }

        private void timer1_Tick ( object sender, EventArgs e ) {
            int i = rand.Next(0, 15);
            // box[i].on(Box0);
        }
    }
    class Box {
        private static Bitmap onBmp, offBmp;
        static Box() {
            onBmp = new Bitmap(100, 100);
            offBmp = new Bitmap(100, 100);
            createBox(onBmp, Color.Red);
            createBox(offBmp, Color.Gainsboro);
        }
        private static void createBox(Bitmap bmp, Color c) {
            Graphics g;
            Brush b;
            g = Graphics.FromImage(bmp);
            b = new SolidBrush(c);
            g.FillRectangle(b, 0, 0, 99, 99);
        }

        public bool enabled;
        public Stopwatch sw;
        public Box () {
            enabled = false;
            sw = new Stopwatch();
        }
        public void on (PictureBox pict) {
            if ( !enabled ) {
                enabled = true;
                pict.Image = onBmp;
                sw.Start();
            }
        }
        public TimeSpan off (PictureBox pict) {
            if ( enabled ) {
                TimeSpan time = sw.Elapsed;
                sw.Stop();
                enabled = false;
                pict.Image = offBmp;
                return time;
            }
            return TimeSpan.Zero;
        }
    }
}

以下の画像が.cs[デザイン]です。
スクリーンショット 2024-04-30 105009.png
一応 .Designer.csの方も載せておきます。

namespace reflexGame {
    partial class Form1 {
        /// <summary>
        /// 必要なデザイナー変数です。
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// 使用中のリソースをすべてクリーンアップします。
        /// </summary>
        /// <param name="disposing">マネージド リソースを破棄する場合は true を指定し、その他の場合は false を指定します。</param>
        protected override void Dispose ( bool disposing ) {
            if ( disposing && ( components != null ) ) {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows フォーム デザイナーで生成されたコード

        /// <summary>
        /// デザイナー サポートに必要なメソッドです。このメソッドの内容を
        /// コード エディターで変更しないでください。
        /// </summary>
        private void InitializeComponent ( ) {
            this.components = new System.ComponentModel.Container();
            this.Start = new System.Windows.Forms.Button();
            this.time = new System.Windows.Forms.Label();
            this.timer1 = new System.Windows.Forms.Timer(this.components);
            this.Box9 = new System.Windows.Forms.PictureBox();
            this.Bo8 = new System.Windows.Forms.PictureBox();
            this.Box12 = new System.Windows.Forms.PictureBox();
            this.Box7 = new System.Windows.Forms.PictureBox();
            this.Box13 = new System.Windows.Forms.PictureBox();
            this.Box6 = new System.Windows.Forms.PictureBox();
            this.Box10 = new System.Windows.Forms.PictureBox();
            this.Box3 = new System.Windows.Forms.PictureBox();
            this.Box11 = new System.Windows.Forms.PictureBox();
            this.Box2 = new System.Windows.Forms.PictureBox();
            this.Box14 = new System.Windows.Forms.PictureBox();
            this.Box5 = new System.Windows.Forms.PictureBox();
            this.Box15 = new System.Windows.Forms.PictureBox();
            this.Box4 = new System.Windows.Forms.PictureBox();
            this.Box1 = new System.Windows.Forms.PictureBox();
            this.Box0 = new System.Windows.Forms.PictureBox();
            this.limit = new System.Windows.Forms.Label();
            this.aveTime1 = new System.Windows.Forms.Label();
            this.aveTime2 = new System.Windows.Forms.Label();
            ((System.ComponentModel.ISupportInitialize)(this.Box9)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.Bo8)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.Box12)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.Box7)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.Box13)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.Box6)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.Box10)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.Box3)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.Box11)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.Box2)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.Box14)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.Box5)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.Box15)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.Box4)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.Box1)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.Box0)).BeginInit();
            this.SuspendLayout();
            // 
            // Start
            // 
            this.Start.Location = new System.Drawing.Point(47, 432);
            this.Start.Name = "Start";
            this.Start.Size = new System.Drawing.Size(98, 51);
            this.Start.TabIndex = 17;
            this.Start.Text = "Start";
            this.Start.UseVisualStyleBackColor = true;
            this.Start.Click += new System.EventHandler(this.button1_Click);
            // 
            // time
            // 
            this.time.AutoSize = true;
            this.time.Font = new System.Drawing.Font("MS UI Gothic", 30F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(128)));
            this.time.Location = new System.Drawing.Point(40, 211);
            this.time.Name = "time";
            this.time.Size = new System.Drawing.Size(105, 40);
            this.time.TabIndex = 18;
            this.time.Text = "00:00";
            // 
            // timer1
            // 
            this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
            // 
            // Box9
            // 
            this.Box9.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
            this.Box9.Location = new System.Drawing.Point(411, 349);
            this.Box9.Name = "Box9";
            this.Box9.Size = new System.Drawing.Size(100, 100);
            this.Box9.TabIndex = 10;
            this.Box9.TabStop = false;
            // 
            // Bo8
            // 
            this.Bo8.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
            this.Bo8.Location = new System.Drawing.Point(305, 349);
            this.Bo8.Name = "Bo8";
            this.Bo8.Size = new System.Drawing.Size(100, 100);
            this.Bo8.TabIndex = 9;
            this.Bo8.TabStop = false;
            // 
            // Box12
            // 
            this.Box12.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
            this.Box12.Location = new System.Drawing.Point(305, 455);
            this.Box12.Name = "Box12";
            this.Box12.Size = new System.Drawing.Size(100, 100);
            this.Box12.TabIndex = 11;
            this.Box12.TabStop = false;
            // 
            // Box7
            // 
            this.Box7.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
            this.Box7.Location = new System.Drawing.Point(623, 243);
            this.Box7.Name = "Box7";
            this.Box7.Size = new System.Drawing.Size(100, 100);
            this.Box7.TabIndex = 8;
            this.Box7.TabStop = false;
            // 
            // Box13
            // 
            this.Box13.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
            this.Box13.Location = new System.Drawing.Point(411, 455);
            this.Box13.Name = "Box13";
            this.Box13.Size = new System.Drawing.Size(100, 100);
            this.Box13.TabIndex = 12;
            this.Box13.TabStop = false;
            // 
            // Box6
            // 
            this.Box6.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
            this.Box6.Location = new System.Drawing.Point(517, 243);
            this.Box6.Name = "Box6";
            this.Box6.Size = new System.Drawing.Size(100, 100);
            this.Box6.TabIndex = 7;
            this.Box6.TabStop = false;
            // 
            // Box10
            // 
            this.Box10.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
            this.Box10.Location = new System.Drawing.Point(517, 349);
            this.Box10.Name = "Box10";
            this.Box10.Size = new System.Drawing.Size(100, 100);
            this.Box10.TabIndex = 13;
            this.Box10.TabStop = false;
            // 
            // Box3
            // 
            this.Box3.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
            this.Box3.Location = new System.Drawing.Point(623, 137);
            this.Box3.Name = "Box3";
            this.Box3.Size = new System.Drawing.Size(100, 100);
            this.Box3.TabIndex = 6;
            this.Box3.TabStop = false;
            // 
            // Box11
            // 
            this.Box11.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
            this.Box11.Location = new System.Drawing.Point(623, 349);
            this.Box11.Name = "Box11";
            this.Box11.Size = new System.Drawing.Size(100, 100);
            this.Box11.TabIndex = 14;
            this.Box11.TabStop = false;
            // 
            // Box2
            // 
            this.Box2.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
            this.Box2.Location = new System.Drawing.Point(517, 137);
            this.Box2.Name = "Box2";
            this.Box2.Size = new System.Drawing.Size(100, 100);
            this.Box2.TabIndex = 5;
            this.Box2.TabStop = false;
            // 
            // Box14
            // 
            this.Box14.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
            this.Box14.Location = new System.Drawing.Point(517, 455);
            this.Box14.Name = "Box14";
            this.Box14.Size = new System.Drawing.Size(100, 100);
            this.Box14.TabIndex = 15;
            this.Box14.TabStop = false;
            // 
            // Box5
            // 
            this.Box5.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
            this.Box5.Location = new System.Drawing.Point(411, 243);
            this.Box5.Name = "Box5";
            this.Box5.Size = new System.Drawing.Size(100, 100);
            this.Box5.TabIndex = 4;
            this.Box5.TabStop = false;
            // 
            // Box15
            // 
            this.Box15.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
            this.Box15.Location = new System.Drawing.Point(623, 455);
            this.Box15.Name = "Box15";
            this.Box15.Size = new System.Drawing.Size(100, 100);
            this.Box15.TabIndex = 16;
            this.Box15.TabStop = false;
            // 
            // Box4
            // 
            this.Box4.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
            this.Box4.Location = new System.Drawing.Point(305, 243);
            this.Box4.Name = "Box4";
            this.Box4.Size = new System.Drawing.Size(100, 100);
            this.Box4.TabIndex = 3;
            this.Box4.TabStop = false;
            // 
            // Box1
            // 
            this.Box1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
            this.Box1.Location = new System.Drawing.Point(411, 137);
            this.Box1.Name = "Box1";
            this.Box1.Size = new System.Drawing.Size(100, 100);
            this.Box1.TabIndex = 2;
            this.Box1.TabStop = false;
            // 
            // Box0
            // 
            this.Box0.BackColor = System.Drawing.Color.Gainsboro;
            this.Box0.Location = new System.Drawing.Point(305, 137);
            this.Box0.Name = "Box0";
            this.Box0.Size = new System.Drawing.Size(100, 100);
            this.Box0.TabIndex = 1;
            this.Box0.TabStop = false;
            this.Box0.Click += new System.EventHandler(this.Box0_Click);
            // 
            // limit
            // 
            this.limit.AutoSize = true;
            this.limit.Location = new System.Drawing.Point(45, 199);
            this.limit.Name = "limit";
            this.limit.Size = new System.Drawing.Size(53, 12);
            this.limit.TabIndex = 19;
            this.limit.Text = "制限時間";
            // 
            // aveTime1
            // 
            this.aveTime1.AutoSize = true;
            this.aveTime1.Location = new System.Drawing.Point(45, 23);
            this.aveTime1.Name = "aveTime1";
            this.aveTime1.Size = new System.Drawing.Size(77, 12);
            this.aveTime1.TabIndex = 20;
            this.aveTime1.Text = "平均反応時間";
            // 
            // aveTime2
            // 
            this.aveTime2.AutoSize = true;
            this.aveTime2.Font = new System.Drawing.Font("MS UI Gothic", 30F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(128)));
            this.aveTime2.Location = new System.Drawing.Point(40, 35);
            this.aveTime2.Name = "aveTime2";
            this.aveTime2.Size = new System.Drawing.Size(133, 40);
            this.aveTime2.TabIndex = 21;
            this.aveTime2.Text = "0:00.00";
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.BackColor = System.Drawing.Color.Silver;
            this.ClientSize = new System.Drawing.Size(821, 628);
            this.Controls.Add(this.aveTime2);
            this.Controls.Add(this.aveTime1);
            this.Controls.Add(this.limit);
            this.Controls.Add(this.Box0);
            this.Controls.Add(this.Box1);
            this.Controls.Add(this.Box4);
            this.Controls.Add(this.time);
            this.Controls.Add(this.Box15);
            this.Controls.Add(this.Start);
            this.Controls.Add(this.Box5);
            this.Controls.Add(this.Box9);
            this.Controls.Add(this.Box14);
            this.Controls.Add(this.Bo8);
            this.Controls.Add(this.Box2);
            this.Controls.Add(this.Box12);
            this.Controls.Add(this.Box11);
            this.Controls.Add(this.Box7);
            this.Controls.Add(this.Box3);
            this.Controls.Add(this.Box13);
            this.Controls.Add(this.Box10);
            this.Controls.Add(this.Box6);
            this.Name = "Form1";
            this.Text = "Form1";
            this.Load += new System.EventHandler(this.Form1_Load);
            ((System.ComponentModel.ISupportInitialize)(this.Box9)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.Bo8)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.Box12)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.Box7)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.Box13)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.Box6)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.Box10)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.Box3)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.Box11)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.Box2)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.Box14)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.Box5)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.Box15)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.Box4)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.Box1)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.Box0)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion
        private System.Windows.Forms.Button Start;
        private System.Windows.Forms.Label time;
        private System.Windows.Forms.Timer timer1;
        private System.Windows.Forms.PictureBox Box9;
        private System.Windows.Forms.PictureBox Bo8;
        private System.Windows.Forms.PictureBox Box12;
        private System.Windows.Forms.PictureBox Box7;
        private System.Windows.Forms.PictureBox Box13;
        private System.Windows.Forms.PictureBox Box6;
        private System.Windows.Forms.PictureBox Box10;
        private System.Windows.Forms.PictureBox Box3;
        private System.Windows.Forms.PictureBox Box11;
        private System.Windows.Forms.PictureBox Box2;
        private System.Windows.Forms.PictureBox Box14;
        private System.Windows.Forms.PictureBox Box5;
        private System.Windows.Forms.PictureBox Box15;
        private System.Windows.Forms.PictureBox Box4;
        private System.Windows.Forms.PictureBox Box1;
        private System.Windows.Forms.PictureBox Box0;
        private System.Windows.Forms.Label limit;
        private System.Windows.Forms.Label aveTime1;
        private System.Windows.Forms.Label aveTime2;
    }
}


0

3Answer

Q1.デザインで直接指定する方法はありません、昔のVBにはあったんですけどね。.net以降にはないです

Q2.やりようはあります

1.pictureBox の配列を作って
pictureBox[0]=pictureBox1
pictureBox[1]=pictureBox2
pictureBox[2]=pictureBox3
と最初に割り当てて
それ以降 pictureBox[0] を使うとか

2.form.findcontrolでコントロール名を指定して操作するとか

3.pictureBoxを返す関数を作って 入力パラメータでindexを渡して
内部でswicth分岐して目的のpictureBoxをreturnするようにするとか
(これならswicth分岐は一か所で済む)

Q3.「Q2」で書いたようにできます
Q4.「Q2」で書いたようにできます

2

Comments

  1. @icoke

    Questioner

    ありがとうございます。とりあえず言われたことを試してみます。

  2. ちょっと記憶違い
    formアプリにfindcontrolないのね。
    こんな感じ

    private void button1_Click(object sender, EventArgs e)
    {
    findPictureBox(1).BackColor = Color.Red;
    findPictureBox(2).BackColor = Color.Blue;
    findPictureBox(3).BackColor = Color.Green;
    }

    private PictureBox findPictureBox(int index)
    {
    return (PictureBox)this.Controls.Find("PictureBox" + index.ToString(), true)[0];
    }

  3. @icoke

    Questioner

    出来ました。
    なんで.Net以降はなくなっちゃったんですかね:sob:
    これで解決したいと思います。
    ありがとうございました。

デザインでは出来ないので、InitializeComponent終わった時点で自力で配列作ってください。
例えばこんな感じで。

    pictureBoxes = this.Controls
        .OfType<PictureBox>()
        .Where(pbx => pbx.Name.StartsWith("Box"))
        .OrderBy(pbx => pbx.TabIndex)
        .ToArray();

NameでOrderByしてもいいですけど、その場合はBox01,02とかにしないと並び順おかしくなります。

1

PictureBoxの数が動的に変化するのではなくデザイナーで配置したものだけなら、愚直に列挙するのがお手軽です。

public class Form1 partial {
  public PictureBox[] PicBoxArray = {};

  public Form1() {
    InitializeComponent();//最初からあるやつ

    PicBoxArray = new PictureBox[] { PictureBox1, PictureBox2, PictureBox3 };
    //C#12以降ならちょっぴりシンプルに書ける
    //PicBoxArray = [ PictureBox1, PictureBox2, PictureBox3 ];
  }
}
1

Your answer might help someone💌