Не удается получить доступ к массиву picturebox - PullRequest
0 голосов
/ 25 февраля 2011

Я создал:

private System.Windows.Forms.PictureBox [] RedBoxes;

Затем в form_load я делаю:

RedBoxes = new PictureBox[20];  
for (int i = 0; i < 20; i++)  
{  
    RedBoxes[i] = new PictureBox();  
    RedBoxes[i].Image = global::IDMTestClient.Properties.Resources.Red;  
    RedBoxes[i].Name = "RedBox" + i.ToString();  
    RedBoxes[i].Size = new Size(1, 38);  
    RedBoxes[i].Location = new Point(i + 10, 32);  
    RedBoxes[i].TabIndex = i + 2;  
    RedBoxes[i].TabStop = false;  
    groupBox3.Controls.Add(RedBoxes[i]);  
    RedBoxes[i].Visible = false;  
    RedBoxes[i].BringToFront();  
}  

Теперь, когда я пытаюсь получить доступ к RedBox в другой функции, он выдает:

"Первое случайное исключение типа 'System.InvalidOperationException' произошло в System.Windows.Forms.dll"

Например:
, когда я:

RedBoxes[i].Left = 10;

или

RedBoxes[i].Location = new Point(10, 32);

Что я делаю не так?

/ ------------------ ОБНОВЛЕНИЕ ------------------- /

base {System.SystemException} = {"Недопустимая операция между потоками: доступ к элементу управления groupBox3из потока, отличного от потока, в котором он был создан. "}

Это то, что есть в RedBoxes [i].Работа WinForms автоматически сгенерированных потоков?

Ответы [ 2 ]

0 голосов
/ 25 февраля 2011

Любые изменения в GUI должны выполняться потоком GUI.Поток GUI также должен быть свободным, чтобы он мог проверять очередь сообщений Windows и перерисовывать приложение время от времени.

Решение состоит в том, чтобы вызывать изменение GUI всякий раз, когда это необходимо, но сохранять фоновые данные в фоновом режиме.

Я создал класс, который наследует Form, который делает это автоматически: http://blog.tedd.no/index.php/2010/07/10/c-net-winforms-gui-thread-invoke-solution/

Там вы также видите, как выполнить вызов.

private delegate void GUIInvokeMethodDelegate(Action @delegate);
/// 
/// Invoke command with GUI thread. Usage: GUIInvoke(() => FormOrControl.Cmd());
/// 
/// Command to execute in form: () => Cmd()
public void GUIInvokeMethod(Action @delegate)
{
    // Check if we need to invoke as GUI thread
    if (this.InvokeRequired)
    {
        this.Invoke(new GUIInvokeMethodDelegate(GUIInvokeMethod), @delegate);
        return;
    }

    // Execute
    @delegate.Invoke();
}

public void DoThisAsGUI() 
{
    GUIInvokeMethod(() => 
    {
        // Something you want to do in GUI thread. 
    }); 
    // or
    GUIInvokeMethod(() => SomeMethodThatRequiresGUIThread());
}

Примечаниечто вы можете изменить «this», например, с помощью экземпляра Form.

0 голосов
/ 25 февраля 2011

убедитесь, что ваш другой метод находится в том же потоке, что и поток пользовательского интерфейса.Изменения из других потоков не допускаются.

Если это действительно другой поток, который вызывает метод, вы можете вызвать метод для установки местоположения следующим образом:

This.Invoke(Delegate to method to invoke,arg as Object)
...