Posted By: Refrax | Feb 16th, 2007 @ 2:32 PM
page 1 of 1
Comments: 4 | Views: 18741
i have been writing up a small app to do some stuff in WPF. at one point i have a file copy with a progressbar. it works fine if i have it in a normal windows form. but will lock up in the wpf window. they both get the job done and the file makes it so it is just something with the progress bar.  can anyone help me with this?
C#

this.progressBar1 = new System.Windows.Forms.ProgressBar();
this.progressBar1.Location = new System.Drawing.Point(12, 12);
this.progressBar1.Name = "progressBar1";
this.progressBar1.Size = new System.Drawing.Size(689, 81);
this.progressBar1.TabIndex = 0;


public void CopyFile(string src, string dst)
{
   System.IO.FileStream SourceFile = new FileStream(src, FileMode.Open, FileAccess.Read, FileShare.None);
   System.IO.FileStream DestFile = new FileStream(dst, FileMode.Append, FileAccess.Write, FileShare.None);
   byte[] buffer = new byte[16384000];
   progressBar1.Maximum = (int)SourceFile.Length / 16384000;
   progressBar1.Minimum = 0;
   progressBar1.Step = 1;
   while (true)
      {
         int read = SourceFile.Read(buffer, 0, buffer.Length);
         if (read <= 0)
            break;
         DestFile.Write(buffer, 0, read);
         progressBar1.PerformStep();
      }
   this.Close();
}
WPF

<ProgressBar Margin="16,10,22,16" Name="progressBar1" />


public void CopyFile(string src, string dst)
{
   System.IO.FileStream SourceFile = new FileStream(src, FileMode.Open, FileAccess.Read, FileShare.None);
   System.IO.FileStream DestFile = new FileStream(dst, FileMode.Append, FileAccess.Write, FileShare.None);
   byte[] buffer = new byte[16384000];   
   progressBar1.Maximum = (int)SourceFile.Length / 16384000;   
   progressBar1.Minimum = 0;
   while (true)
   {
      int read = SourceFile.Read(buffer, 0, buffer.Length);
      if (read <= 0)
         break;
      DestFile.Write(buffer, 0, read);
      progressBar1.Value += 1;
   }
   this.Close();
}

littleguru
littleguru
<3 Seattle
The WPF progressbar does not have a Step property, I suppose (just a shoot in the dark).
footballism
footballism
Another Paradigm Shift!
    You are updating the ProgressBar in a tight loop, and you presume that the ProgressBar will update its display, but in reality, the ProgressBar cannot update itself, because the Dispatcher is busy processing the current work item which contains CopyFile code, when the Dispatcher finishes processing the current work item, the ProgressBar's display will get updated, but it will show in the "full" mode, because its Value property gets mounted into the max in your previous work item. one possible workaround to your problem is using the foreground thread as follows:
while (true)
   {
      int read = SourceFile.Read(buffer, 0, buffer.Length);
      if (read <= 0)
         break;
      DestFile.Write(buffer, 0, read);
      progressBar1.Value += 1;
progressBar1.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Send, new System.Threading.ThreadStart(delegate
            {
                progressBar1.Value += 1;
            }));
   }
the Dispatcher.Invoke does what SendMessage does in win32 and Control.Invoke in Windows Forms.
    or you can use the background worker thread to do the blocking file copy operation, and update the UI using cross thread  marshalling, the BackgroundWorker class comes at handy, Pavan has a blog article talking about how to use the BackgroundWorker the WPF:
http://pavanpodila.spaces.live.com/blog/cns!9C9E888164859398!246.entry

I recommend you to use background thread here, because executing blocking operation in foreground thread is not a good way of doing UI.

Sheva
page 1 of 1
Comments: 4 | Views: 18741
Microsoft Communities