2012-06-07 5 views
1

У меня есть много PictureBox es с именами picturebox_D1, picturebox_D2 ... D30.Название изображения

Что я хотел бы сделать, это изменить изображения в этих PictureBox es, но в цикле. Что-то вроде этого, но работает

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"); 
} 

Как это сделать?

ответ

2

Вы можете использовать индексацию управления родительского контейнера, чтобы получить контроль по имени. Например: Если PictureBoxes просто поместить прямо на форме (т.е. не в панели, GroupBox или другой контейнер):

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

Для вложенных PictureBoxes (т.е. те, в пределах рамок группы или групп), просто взять Такой же подход, но на родительском контейнере:

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» бессмысленна после компиляции кода и не имеет смысла для компилятора.

+1

Это будет работать при условии, что имена были правильно установлены – GETah

+0

OP заявила в первой строке своего вопроса, что PictureBoxes правильно названы –

+1

Учитывая, что параметры вопроса были «У меня много PictureBoxes с именами picturebox_D1, picturebox_D2 ... D30 ». Я бы сказал, что это логично, что их называют так. –

0

мне пришлось иметь дело с подобной ситуацией некоторое время назад, когда я имел имена переменных var1, var2 ...

Лучший способ, которым я мог найти, чтобы обойти имея дело переключатель монстр использовать отражение. Учитывая название поля изображения, вы можете легко найти переменную, используя отражение. Это должно работать:

// 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"); 
} 
0

Лучший способ сделать это было бы создать PictureBox массив и заполнить его с PictureBoxes как это:

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

, то вы можете перебирать их

foreach(var p in pictures) 
{ 
    p.Image = new Bitmap(@"Pictures\\green.png"); 
} 
0

В вашем конструкторе создайте и установите локальный Dictionary<string, PictureBox>. Помните, что формы являются классами, как и любой другой класс C#, и их следует рассматривать как таковые.

Вместо for, теперь вы можете использовать foreach и получить доступ к .Key и .Value, чтобы получить имена файлов и PictureBox объектов. Это работает только потому, что у вас есть такие жесткие отношения между PictureBox и желаемое. Если спаривание изменится или вы хотите использовать одно и то же изображение для двух изображений, вы должны изменить это на List<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); 
} 
0

Очень простое решение:

PictureBox mybox = (PictureBox)this.Controls.Find("pictureBox2", true)[0]; 
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 называется), и у вас есть эта коллекция повторно использовать для остальная часть жизни формы. Это также гарантирует, что если вы добавите дополнительные PictureBoxes (которые следуют одному и тому же соглашению об именах), вам не нужно ничего менять.

Смежные вопросы