Multithreaded Panel Visiblility

N

nullmind

Hi everyone,
I've got myself a C# .NET 1.1 application I'm making where a docked
Panel that contains some progress bars etc. is being toggled between
Visible and not. Basically a user drags some photos into the window and
it activates a background thread that shows the panel, does some work,
and hides it again. If this is not in a separate thread, it works! I've
tried doing a manual Update(), and PerformLayout() calls, but nothing
works. The thread work happens, but the panel never shows. I've also
tried Application.DoEvents().

private void itemImages_DragDrop(object sender,
System.Windows.Forms.DragEventArgs e) {
ArrayList formats = new ArrayList(e.Data.GetFormats());

if(formats.Contains(DataFormats.FileDrop)){
//imageImportFiles =
(string[])e.Data.GetData(DataFormats.FileDrop);
imageImportFiles.Clear();
imageImportFiles.AddRange((string[])e.Data.GetData(DataFormats.FileDrop));

imageImportThread = new Thread(new ThreadStart(this.importImages));
imageImportThread.Start();
}
}


private void importImages(){
imageImportPanel.Visible = true;
imageLoadProgress.Maximum = imageImportFiles.Count;
imageLoadProgress.Value = 0;

ArrayList imageFiles = new ArrayList();

foreach(string filePath in imageImportFiles){
importDirectory(filePath, imageFiles);
}

imageLoadProgress.Maximum = imageFiles.Count;
imageLoadProgress.Value = 0;

foreach(string filePath in imageFiles){
string label = getFileName(filePath);
Image img;
int imgId;
ListViewItem item;

imageImportStatus.Text = String.Format("Importing {0}... ({1} of
{2})",
label, imageLoadProgress.Value+1, imageLoadProgress.Maximum);

Application.DoEvents();

try{
img = Image.FromFile(filePath);
}catch(Exception){
continue;
}

imgId = itemImageList.Images.Add(img, Color.Transparent);
item = itemImages.Items.Add(label, imgId);
imageLoadProgress.Value++;
}

imageImportPanel.Visible = false;
}
 
A

Andrew Smith \(Infragistics\)

You're not supposed to interact with objects on the ui thread from a
background thread. You should make calls back into the ui thread using a
control's Invoke or BeginInvoke method and interact with the controls from
there. Also, I'd recommend avoiding DoEvents calls since that can lead to
re-entrancy issues, etc. You might want to check a couple of ms articles on
safely marshalling from a background thread to the ui thread.
e.g.
http://msdn.microsoft.com/msdnmag/issues/03/02/Multithreading/default.aspx
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnforms/html/winforms06112002.asp
 
J

Jon Skeet [C# MVP]

I've got myself a C# .NET 1.1 application I'm making where a docked
Panel that contains some progress bars etc. is being toggled between
Visible and not. Basically a user drags some photos into the window and
it activates a background thread that shows the panel, does some work,
and hides it again. If this is not in a separate thread, it works! I've
tried doing a manual Update(), and PerformLayout() calls, but nothing
works. The thread work happens, but the panel never shows. I've also
tried Application.DoEvents().

<snip>

You need to follow the golden rules of WinForms threading: don't access
the UI on the wrong thread.

See http://www.pobox.com/~skeet/csharp/threads/winforms.shtml
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top