Progress bar without GUI code in the model?

  • Thread starter Thread starter bob
  • Start date Start date
B

bob

Hello,

I want to show progress to the user while some method is running so I
thought I'd use a progress bar.

But I don't see how I can do this without writing GUI code in the
model?

In Smalltalk I would fire of notification exceptions that a progress
bar would catch, increment progress, and then allow to continue (or no
one would catch and would perform their default behaviour which was to
continue). I gather that's not possible because Exceptions in C#
cannot be resumable?

Any ideas?

Thanks,
Bob
 
Hi Bob,

Using an exception for this is not recommended, in fact an exception should
only be used when an error occur, do never use exceptions to control the
flow of a program, the exceptions are VERY EXPENSIVES !!!.

You have to use a event for this, below I post a code snap that do
precisely that.
Basically I'm resizing images files, I do so in a worker thread and in the
main thread ( UI thread ) I use a progressbar as well as a couple of labels.

I post here the important part of the code, all the code will found below.

// This is the delegate I Will use to notify the interface a new file was
processed
public delegate void ProcessedFileHandler( );
// thre thread
Thread workingThread;
// This will "point" to the function to update the UI
ProcessedFileHandler procfilehandler;


private void ImportImages_Load(object sender, System.EventArgs e)
{
// The method I will call to update the UI
procfilehandler = new ProcessedFileHandler( this.UpdateProgressBar);
//Start the thread
this.workingThread = new Thread( new ThreadStart( this.ImportImage ));
this.workingThread.Start();
}

// This is the working method, I iterate in the file list and process each
file , at the end I call the method to update the interface
// the trick is to use a WinForm control and call Invoke on it, it can be
ANY UI control, all it does is MAKE SURE that the call
// is done in the main thread.
void ImportImage( )
{
foreach(string imageURL in files)
{
try
{

//Update the interface, this MAKE SURE the call is done in the main
thread
this.progressBar1.Invoke( procfilehandler, null);
}
catch(Exception e)
{
continue;
}
}
}


//The update UI method:
void UpdateProgressBar( )
{
this.progressBar1.Value++;
FileNameLBL.Text = currentfile;
currentLBL.Text = currentpos.ToString();
}


Here is the code completed, just for reference !!!.

Hope this help,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation

//*********************** CODE START

using System;
using System.Data;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Text;
using System.IO;
using System.Threading;

namespace WindowsApplication1
{
/// <summary>
/// Summary description for ImportImages.
/// </summary>
public class ImportImages : System.Windows.Forms.Form
{
public delegate void ProcessedFileHandler( );

Thread workingThread;
object syslock = new object();
int currentpos=0;
string currentfile="";
string[] files;
ProcessedFileHandler procfilehandler;


private System.Windows.Forms.ProgressBar progressBar1;
private System.Windows.Forms.Label FileNameLBL;
private System.Windows.Forms.Label currentLBL;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label1;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;

public ImportImages(string[] files)
{
//
// Required for Windows Form Designer support
//
InitializeComponent();

//
// TODO: Add any constructor code after InitializeComponent call
//
this.files = files;
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.progressBar1 = new System.Windows.Forms.ProgressBar();
this.FileNameLBL = new System.Windows.Forms.Label();
this.currentLBL = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// progressBar1
//
this.progressBar1.Location = new System.Drawing.Point(16, 144);
this.progressBar1.Name = "progressBar1";
this.progressBar1.Size = new System.Drawing.Size(264, 23);
this.progressBar1.TabIndex = 1;
//
// FileNameLBL
//
this.FileNameLBL.Location = new System.Drawing.Point(16, 208);
this.FileNameLBL.Name = "FileNameLBL";
this.FileNameLBL.Size = new System.Drawing.Size(208, 16);
this.FileNameLBL.TabIndex = 2;
this.FileNameLBL.Text = "label1";
//
// currentLBL
//
this.currentLBL.Location = new System.Drawing.Point(176, 184);
this.currentLBL.Name = "currentLBL";
this.currentLBL.Size = new System.Drawing.Size(56, 16);
this.currentLBL.TabIndex = 3;
this.currentLBL.Text = "label2";
this.currentLBL.TextAlign = System.Drawing.ContentAlignment.TopRight;
//
// label3
//
this.label3.Location = new System.Drawing.Point(240, 184);
this.label3.Name = "label3";
this.label3.TabIndex = 4;
this.label3.Text = "label3";
//
// label1
//
this.label1.Location = new System.Drawing.Point(16, 176);
this.label1.Name = "label1";
this.label1.TabIndex = 5;
this.label1.Text = "Processing:";
this.label1.TextAlign = System.Drawing.ContentAlignment.BottomLeft;
//
// ImportImages
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 273);
this.Controls.Add(this.label1);
this.Controls.Add(this.label3);
this.Controls.Add(this.currentLBL);
this.Controls.Add(this.FileNameLBL);
this.Controls.Add(this.progressBar1);
this.Name = "ImportImages";
this.Text = "ImportImages";
this.Load += new System.EventHandler(this.ImportImages_Load);
this.ResumeLayout(false);

}
#endregion

void UpdateProgressBar( )
{
this.progressBar1.Value++;
FileNameLBL.Text = currentfile;
currentLBL.Text = currentpos.ToString();
}

void Done()
{
MessageBox.Show("Done");
this.Close();
}


void ImportImage( )
{
Image.GetThumbnailImageAbort myCallback =
new Image.GetThumbnailImageAbort(ThumbnailCallback);

//Images are in the form ID.extension
foreach(string imageURL in files)
{
try
{

DataRow prow = GetProductRow( Path.GetFileNameWithoutExtension(
imageURL) );
// if ( prow == null)
// continue; //product not found.
//See if the Image is correct in size, if not try to resize it
Image image = new Bitmap( imageURL);
if ( (image.Width> Config.MaxImageWidth) || (image.Height>
Config.MaxImageHeight) )
{
//Resize the image
Image newimage = image.GetThumbnailImage( Math.Min( image.Width,
Config.MaxImageWidth) ,
Math.Min( image.Height, Config.MaxImageHeight) ,
myCallback, IntPtr.Zero);
ExportImage( newimage,
Path.GetFileName(imageURL) );//prow["ProductID"].ToString() );
}
else
ExportImage( image,
Path.GetFileName(imageURL) );//prow["ProductID"].ToString() );

lock( this.syslock)
{
this.currentpos++;
this.currentfile = Path.GetFileName(imageURL);
}
//Update the interface
this.progressBar1.Invoke( procfilehandler, null);
}
catch(Exception e)
{
continue;
}
}
this.progressBar1.Invoke( new ProcessedFileHandler( this.Done), null);
}
//Just save the image to the new directory under the new name
void ExportImage( Image image, string newname)
{
image.Save( Config.ExportImageDirectory + @"\" + newname,
System.Drawing.Imaging.ImageFormat.Jpeg);
}
DataRow GetProductRow( string origID )
{
// foreach(DataRow prow in DataProvider.StaticData.Tables["Product"].Rows)
// if ( prow["OriginalID"].ToString() == origID)
// return prow;
return null;

}
public bool ThumbnailCallback()
{
return false;
}



private void ImportImages_Load(object sender, System.EventArgs e)
{
this.label3.Text = "of " + files.Length.ToString();
this.progressBar1.Minimum = 0;
this.progressBar1.Maximum = files.Length;
procfilehandler = new ProcessedFileHandler( this.UpdateProgressBar);
//Start the thread
this.workingThread = new Thread( new ThreadStart( this.ImportImage ));
this.workingThread.Start();
}
}


class Config
{
public static int MaxImageWidth = 200;
public static int MaxImageHeight = 200;
public static string ExportImageDirectory = @"c:\temp";
public static string ExportImageDirectoryPPC = @"c:\temp";
}
}


//********************** CODE END
 
Back
Top