Solved

Progress Bar

Posted on 2015-01-15
6
144 Views
Last Modified: 2015-01-29
Hi All,

Greetings!

I am developing a desktop application using C# winForms. In this application i am sending the bulk emails to recipients. I want to develop a progress bar as shown in attached snap shot.

Please help me to achieve.

Thanks in advance.
progressbar.png
0
Comment
Question by:Jatin Nahar
6 Comments
 
LVL 35

Expert Comment

by:Kimputer
Comment Utility
Do you mean you want it to look exactly like the picture (you already know basic coding, except for it to look like that), or just basic code (with the basic built-in winforms progress bar)?
0
 
LVL 32

Accepted Solution

by:
Stefan Hoffmann earned 500 total points
Comment Utility
Well, there are a lot of free or almost free component suites out there, e.g. SyncFusions Community License. But if you would do it on your own, here's an MSDN article about it:

How to create a smooth progress bar in Visual C#
0
 
LVL 16

Expert Comment

by:Rose Babu
Comment Utility
Hi Jatin Nahar,

Try the below code which looks like the one you wanted...

private void button1_Click(object sender, EventArgs e)
{
	int percent = (int)(((double)progressBar1.Value / (double)progressBar1.Maximum) * 100);
	progressBar1.CreateGraphics().DrawString(percent.ToString() + "%", new Font("Arial", (float)8.25, FontStyle.Regular), Brushes.Black, new PointF(progressBar1.Width / 2 - 10, progressBar1.Height / 2 - 7));
	
	int emailMinCountVal = 0;
	int emailMaxCountVal = 200; // Reset it with your total email count

	progressBar1.Minimum = emailMinCountVal;
	progressBar1.Maximum = emailMaxCountVal;

	progressBar1.Value = emailMinCountVal;

	for (int i = 0; i <= emailMaxCountVal; i++)
	{
		// Your email goes here as one by one

		progressBar1.Value = i;                           
		
		percent = (int)(((double)progressBar1.Value / (double)progressBar1.Maximum) * 100);
		progressBar1.CreateGraphics().DrawString(percent.ToString() + "%", new Font("Arial", (float)8.25, FontStyle.Regular), Brushes.Black, new PointF(progressBar1.Width / 2 - 10, progressBar1.Height / 2 - 7));
	
		// Set some sleep time if you need . May be the email process will take some seconds of time. So sleep may not required
		Thread.Sleep(10);
	}

	progressBar1.CreateGraphics().DrawString("100%", new Font("Arial", (float)8.25, FontStyle.Regular), Brushes.Black, new PointF(progressBar1.Width / 2 - 10, progressBar1.Height / 2 - 7));
	
}

Open in new window

For coloring the progressbar try the tutorials in the below URL

http://www.codeproject.com/Tips/292948/Glass-Style-ProgressBar

http://www.codeproject.com/Articles/21302/Custom-ProgressBar-for-NET-Compact-Framework

Hope this will help you.

--
Rose
0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 19

Expert Comment

by:Daniel Van Der Werken
Comment Utility
The core problem with progress bars in windows applications is the fact that you're trying to update a UI element from within a thread.

As a result, you will get an error when trying to update a progress bar. I think that might be the core issue here. You need to do some asynchronous programming with delegates and invoking:

As described in the link I provide, you want to set the property on a control:

private delegate void SetControlPropertyThreadSafeDelegate(Control control, string propertyName, object propertyValue);

public static void SetControlPropertyThreadSafe(Control control, string propertyName, object propertyValue)
{
  if (control.InvokeRequired)
  {
    control.Invoke(new SetControlPropertyThreadSafeDelegate(SetControlPropertyThreadSafe), new object[] { control, propertyName, propertyValue });
  }
  else
  {
    control.GetType().InvokeMember(propertyName, BindingFlags.SetProperty, null, control, new object[] { propertyValue });
  }
}

Open in new window


So, I updated a label in my windows forms application in the loop that does the work, I added this:

SetControlPropertyThreadSafe(lblOutputCount, "Text", i.ToString());

Where lblOutputCount is the name of my label, "Text" is the name of the property (every label has this), and the value I want to display is my iterator (i).

You would then pass in your control (the progress bar) as the control, the property (percentage) and the value same as I did.
0
 
LVL 32

Expert Comment

by:it_saige
Comment Utility
It suprises me that no one mentioned the BackgroundWorker.  Don't get me wrong, Dan7l, I personally use an extension method when I have doubt's about when a control will be accessed (via the UI thread or some other thread).  But when I know that a control is going to be accessed via a non-UI thread, I lean on the BackgroundWorker.

Example -

Form1.cs -
using System;
using System.ComponentModel;
using System.Windows.Forms;

namespace EE_Q28597243
{
	public partial class Form1 : Form
	{
		public Form1()
		{
			InitializeComponent();
		}

		private void OnClick(object sender, EventArgs e)
		{
			worker.RunWorkerAsync();
		}

		private void OnDoWork(object sender, DoWorkEventArgs e)
		{
			// Put your logic to actually process emails here.
			for (int i = 0; i < 28; i++)
			{
				worker.ReportProgress(((100 * (i + 1)) / 28), new object[] { i + 1, "28" });
				System.Threading.Thread.Sleep(1500);
			}
		}

		private void OnProgressChanged(object sender, ProgressChangedEventArgs e)
		{
			object[] state = (object[])e.UserState;
			progressBar1.Value = e.ProgressPercentage;
			label1.Text = string.Format("Processed {0} of {1} emails", state[0], state[1]);
		}
	}
}

Open in new window

Form1.Designer.cs -
namespace EE_Q28597243
{
	partial class Form1
	{
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.IContainer components = null;

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing && (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.btnSend = new System.Windows.Forms.Button();
			this.worker = new System.ComponentModel.BackgroundWorker();
			this.progressBar1 = new System.Windows.Forms.ProgressBar();
			this.label1 = new System.Windows.Forms.Label();
			this.SuspendLayout();
			// 
			// btnSend
			// 
			this.btnSend.Location = new System.Drawing.Point(107, 120);
			this.btnSend.Name = "btnSend";
			this.btnSend.Size = new System.Drawing.Size(75, 23);
			this.btnSend.TabIndex = 1;
			this.btnSend.Text = "Send Emails";
			this.btnSend.UseVisualStyleBackColor = true;
			this.btnSend.Click += new System.EventHandler(this.OnClick);
			// 
			// worker
			// 
			this.worker.WorkerReportsProgress = true;
			this.worker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.OnDoWork);
			this.worker.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.OnProgressChanged);
			// 
			// progressBar1
			// 
			this.progressBar1.Location = new System.Drawing.Point(12, 150);
			this.progressBar1.Name = "progressBar1";
			this.progressBar1.Size = new System.Drawing.Size(264, 23);
			this.progressBar1.TabIndex = 2;
			// 
			// label1
			// 
			this.label1.AutoSize = true;
			this.label1.BackColor = System.Drawing.Color.Transparent;
			this.label1.Location = new System.Drawing.Point(12, 176);
			this.label1.Name = "label1";
			this.label1.Size = new System.Drawing.Size(35, 13);
			this.label1.TabIndex = 3;
			this.label1.Text = "label1";
			// 
			// Form1
			// 
			this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
			this.ClientSize = new System.Drawing.Size(288, 262);
			this.Controls.Add(this.label1);
			this.Controls.Add(this.progressBar1);
			this.Controls.Add(this.btnSend);
			this.Name = "Form1";
			this.Text = "Form1";
			this.ResumeLayout(false);
			this.PerformLayout();

		}

		#endregion

		private System.Windows.Forms.Button btnSend;
		private System.ComponentModel.BackgroundWorker worker;
		private System.Windows.Forms.ProgressBar progressBar1;
		private System.Windows.Forms.Label label1;

	}
}

Open in new window

Sample of produced output -Capture.JPGCapture.JPG
0
 

Author Closing Comment

by:Jatin Nahar
Comment Utility
good
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Suggested Solutions

This document covers how to connect to SQL Server and browse its contents.  It is meant for those new to Visual Studio and/or working with Microsoft SQL Server.  It is not a guide to building SQL Server database connections in your code.  This is mo…
Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
This video discusses moving either the default database or any database to a new volume.
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now