1

PictureBox私は、picturebox_D1、picturebox_D2... D30 という名前の es をたくさん持っています。

私がやりたいのは、それらのPictureBoxes の画像を変更することですが、ループ内です。このようなものですが、動作しています

for (int i = 0; i < 30; i++)
{                     
    if (ReceivedDataTextBox.Text[i].ToString()=="1") 
        "pictureBox_D"+i.Image= new Bitmap(@"Pictures\\green.png");
    else 
        "pictureBox_D"+i.Image= new Bitmap(@"Pictures\\red.png");
}

どうすればいいですか?

4

6 に答える 6

2

親コンテナーのコントロールのインデックス作成を使用して、名前でコントロールを取得できます。例: ピクチャ ボックスがフォームに直接配置されている場合 (つまり、Panel、GroupBox、またはその他のコンテナに配置されていない場合):

for(int i = 0; i < 30; i++)
{
    ((PictureBox)this.Controls["pictureBox_D" + i.ToString()]).Image = new Bitmap(@"Pictures\\green.png");
}

ネストされた PictureBoxes (つまり、GroupBoxes または Panels 内のもの) の場合は、親コンテナーに対して同じ方法を使用します。

for(int i = 0; i < 30; i++)
{
    ((PictureBox)this.panel1.Controls["pictureBox_D" + i.ToString()]).Image = new Bitmap(@"Pictures\\green.png");
}

表面的には、文字列を入力するだけで変数を参照できるようになるのは当然のことのように思えるかもしれませんが、C# を深く掘り下げ始めると、これが C# で実際に機能する方法ではないことに気付くでしょう。IDE に書き込むコードはコンパイルされます。そのコンパイル中に、高レベル コード (変数名、関数名など) に関するすべての優れた機能が失われます。コードがコンパイルされると、「pictureBox_D」文字列は無意味になり、コンパイラには意味がありません。

于 2012-06-07T14:42:18.817 に答える
0

非常に簡単な解決策:

PictureBox mybox = (PictureBox)this.Controls.Find("pictureBox2", true)[0];
于 2012-06-07T14:44:17.887 に答える
0

これを行う最善の方法は、PictureBox配列を作成し、次のようにピクチャ ボックスで埋めることです。

PictureBox[] pictures = {picturebox_D1, picturebox_D2, ...};

その後、それらを反復できます

foreach(var p in pictures)
{
    p.Image = new Bitmap(@"Pictures\\green.png");
}
于 2012-06-07T14:40:48.900 に答える
0

コンストラクターで local を作成して設定しますDictionary<string, PictureBox>。フォームは他の C# クラスと同様のクラスであり、そのように扱う必要があることに注意してください。

の代わりにfor、 と を使用foreachしてアクセスし、ファイル名とオブジェクトを取得できるように.Keyなりました。ただし、これは、名前と目的の画像の間に非常に厳密な関係があるためにのみ機能します。ペアリングが変更された場合、または 2 つの画像ボックスに同じ画像を使用したい場合は、これを. 実際、それは状況を処理するための最善の方法でさえあるかもしれません..ValuePictureBoxPictureBoxList<Tuple<string, PictureBox>>

public class Form1 : Form
{
    private Dictionary<string, PictureBox> pictureBoxes;

    public Form1()
    {
        pictureBoxes = new Dictionary<string, PictureBox>()
        {
              {"Pictures\\green.png", pictureBox_D},
              {"Pictures\\blue.png", pictureBox_B},
              // Etcetera
        }
    }
}

それらをループしたい場合は、次のようにします。

foreach(var kvp in pictureBoxes)
{
    kvp.Value.Image = new Bitmap(kvp.Key);
}
于 2012-06-07T14:42:01.083 に答える
0

Controls.OfType<PictureBox>()LINQ と組み合わせて使用​​すると、必要なアイテムを取得できます。実際、それらすべてを使用可能なコレクションに変換できる可能性があります。

var picBoxes = this.Controls
                    .OfType<PictureBox>()
                    .Where(pb => pb.Name.StartsWith("pictureBox_D"))
                    .ToDictionary(pb => int.Parse(pb.Name.Replace("pictureBox_D", string.Empty)));
for(int i = 0; i < picBoxes.Length; i++)
{
    // Do what you need with picBoxes[i]
}

良い点は、これをコンストラクターで (InitializeComponent呼び出した後に) 1 回実行でき、このコレクションをフォームの残りの期間に再利用できることです。これにより、追加の PictureBoxes (同じ命名規則に従うもの) を追加した場合でも、何も変更する必要がないことが保証されます。

于 2012-06-07T15:00:21.670 に答える
0

I had to deal with a similar situation sometime ago where I had variable names var1, var2, ...

The best way I could find to get around having a monster switch case is to use reflection. Given the name of the picture box, you can easily find out the variable itself using reflection. This should work:

// Assuming this is inside the form where the pictures boxes are hosted
for (int i = 0; i < 30; i++){
    FieldInfo field = GetType().GetField("pictureBox_D"+i, flags);
    PictureBox pictureBox = (PictureBox)field.GetValue(this);
    if (ReceivedDataTextBox.Text[i].ToString()=="1") 
        pictureBox.Image= new Bitmap(@"Pictures\\green.png");
    else 
        pictureBox.Image= new Bitmap(@"Pictures\\red.png");
}
于 2012-06-07T14:40:04.330 に答える