 |
|
|
 |
|
|
 |
|
|
 |
|
 |
Thanks for opening my eyes to the [Category] decoration.
Elegant stuff.
kls
|
|
|
|
 |
|
 |
The control does not seem to update while the program is doing "work.
For example, taking the example given, if we add a forever loop to the "start" button press, the control wont update as it should (given its running in another thread).
private void button2_Click(object sender, System.EventArgs e)
{
this.statusBarPanel2.StartAnimation();
while(true)
{
;
}
}
Unfortuanatly, the only time I want the progress bar to update is while the program is busy.
I've tried forcing updates to the bar, using timers and doing my work function in a new thread. Nothing seems to work. Any Ideas?
Thanks
Ryan
|
|
|
|
 |
|
 |
you can try the following line, butt still I don't think this is the best way:
private void button2_Click(object sender, System.EventArgs e)
{
this.statusBarPanel2.StartAnimation();
while(true)
{
System.Threading.Thread.CurrentThread.Join(1);
}
}
b
|
|
|
|
 |
|
 |
Nice job.
Here's something to make the StatusBarProgressPanel a little more user friendly. You can force the Style to OwnerDraw. Since the base class doesn't mark the Style property as virtual, you have to use the new modifier to hide the inherited member.
First, declare the new property:
[DefaultValue(2),Category("Appearance")]
public new StatusBarPanelStyle Style
{
get
{
return base.Style;
}
}
Then add this line to the constructor:
base.Style = StatusBarPanelStyle.OwnerDraw;
The nice thing about this is that is disallows the user from changing the value to "Text" and causing the graphics not to work. If you prefer, you can choose to hide the Style property altogether in the designer by applying the Browsable(false) attribute.
|
|
|
|
 |
|
 |
I think there should be an easy way to update the progress bar to any position you would like at any time. Instead this must be done by setting the step size as 0, setting the progressPosition to the position you want and the calling the step function. I added a method for this in my code and was wondering if anyone else thinks this would be a useful addition. Just a suggestion for the author. Thanks so much for the great code, much appreciated here!
|
|
|
|
 |
|
 |
First - Thanks for this control.
Second -
A small bug fix that will address winryan problem :
just add the "if" statement to the ProgressPosition setter and setting the current position will trigger update of the control without having to call the step function.
[Category("Measurement")]
public long ProgressPosition
{
get
{
return _currentPosition;
}
set
{
_currentPosition = value;
if(this.Parent != null)
this.Parent.Invoke( _refreshDelegate );
}
}
One more suggestion can be keeping the signature of the control as close as possible to the original control.
Thanks again .
A .
|
|
|
|
 |
|
 |
Thanks for this control it saved my bacon when I had to downgrade a .NET2 statusStrip to a .NET1 statusBar (For custom skinning reasons)
After implementing the above posts modifications I was getting an exception thrown of 'Invoke or BeginInvoke cannot be called on a control until the window handle has been created.' when I called the following line
this.Parent.Invoke( _refreshDelegate );
This was due to the fact that something in my program was trying to use the control before the main form had been fully initialised. Fortunately with a little addition to this control it was easy to fix.
First of all modify the ProgressPosition assessor so that it is
[Category("Measurement")]
public long ProgressPosition
{
get
{
return _currentPosition;
}
set
{
_currentPosition = value;
if (this.Parent != null && _isHandleCreated == true)
this.Parent.Invoke( _refreshDelegate );
}
}
Then add the following code to the control
private bool _isHandleCreated = false;
[Category("Crash Protection")]
public bool IsHandleCreated
{
set
{
_isHandleCreated = value;
}
}
Finally add something like this code to the form that the control is on
public Form1()
{
InitializeComponent();
this.HandleCreated += new EventHandler(Form1_HandleCreated);
}
void Form1_HandleCreated(object sender, EventArgs e)
{
statusBarPanel2.IsHandleCreated = true;
//throw new Exception("The method or operation is not implemented.");
}
I found this way easier to do than trawling through the code trying to find out what had set off the progress bar on the status bar early.
-- modified at 12:27 Wednesday 13th September, 2006
|
|
|
|
 |
|
 |
First let me start by saying this is an excellent article and exactly what I needed.
However, I did have a minor modification that was necessary for how I'm using it. If the calls to step occur very frequently, the user gets a nasty flicker when the progress bar updates. This is easily rectified by using double-buffering when redrawing the progress bar.
All that is necessary to do this is to first declare 2 new class members:
private Bitmap offScreenBmp = null;
private Graphics offScreenDC = null;
Next add the following function:
private void DrawPanel()
{
Graphics graphics = this.Parent.CreateGraphics();
Rectangle eventBounds = new Rectangle(
this.Parent.Width - this.Width + 3, 3,
this.Width-4, this.Parent.Height-4 );
if( offScreenBmp == null )
{
offScreenBmp = new Bitmap( eventBounds.Width,
eventBounds.Height );
offScreenDC = Graphics.FromImage(offScreenBmp);
}
Rectangle fullBounds = eventBounds;
fullBounds.X = 0;
fullBounds.Y = 0;
offScreenDC.FillRectangle( SystemBrushes.Control, fullBounds );
if (_currentPosition != _startPoint )
{
if ( ( _currentPosition <= _endPoint ) ||
(this.AnimationStyle == ProgressDisplayStyle.Infinite) )
{
Rectangle bounds = eventBounds;
float percent = ( (float)_currentPosition /
((float)_endPoint - (float)_startPoint) );
switch ( this.AnimationStyle )
{
// several cases
}
// draw the progress bar
bounds.X = 0;
bounds.Y = 0;
offScreenDC.FillRectangle( _progressBrush, bounds );
if ( this.ShowText )
{
// draw the text on top of the progress bar
offScreenDC.DrawString((percent * 100).ToString(),
_textFont, _textBrush, eventBounds);
}
}
}
graphics.DrawImage(offScreenBmp, eventBounds.X, eventBounds.Y);
}
This is essentially the same code as used before just with the double-buffering tweaks. Note that I didn't rewrite all of the case statements here to shorten my post.
Lastly, replace all of the
this.Parent.Invoke( _refreshDelegate );
calls with
DrawPanel
And that's it! No more flicker.
|
|
|
|
 |
|
 |
Hey thanks for that, Corey. Worked for me.
I'm confused about removing the this.Parent.Invoke( _refreshDelegate ) business... was it there to help in some threading context?
|
|
|
|
 |
|
 |
First off, I wanted to say that I think this is a wonderful article.
For some reason, when the progress bar draws, the background of the status panel turns white, and stays that way after the progress bar has been reset.
I have tried chainging the drawing brushes, but it hasnt helped.
Any suggestions?
I am using Visual Studio 7.0
Phil
|
|
|
|
 |
|
 |
Great article!
I have a question on how to use your inherited control class 'StatusBarProgressPanel'. When adding a status bar panel in design mode using 'Add' button in dialog, the default 'System.Windows.Forms.StatusBarPanel' will be added and below code will be generated automatically:
private System.Windows.Forms.StatusBarPanel statusBarPanel1;
this.statusBarPanel1 = new System.Windows.Forms.StatusBarPanel();
In your source code, how to generate the code like:
private StatusBarProgressPanel statusBarPanel2;
this.statusBarPanel2 = new StatusBarTest.StatusBarProgressPanel();
I have a way to replace source code from 'System.Windows.Forms.StatusBarPanel' to 'StatusBarProgressPanel' manually, but the 'StatusBarProgressPanel' can be used in design mode directly? I mean when click 'Add' button, your 'StatusBarProgressPanel' will be automatically added in design dialog and 'StatusBarProgressPanel' code will be automatically generated.
Icey
w14243@email.mot.com
|
|
|
|
 |
|
 |
Good question!
I just changed it from the source view. If anybody knows how to trick the designer out, let me know and I'll update the article with the info.
-slf
|
|
|
|
 |
|
 |
I think you need to make a new StatusBar implementation. It should be as simple as inheriting the standard one and exchanging the StatusBarPanel with your StatusBarProgressPanel.
|
|
|
|
 |
|
 |
But how the screenshot of 'StatusBarPanel Conllection Edit' dialog comes out?
|
|
|
|
 |
|
 |
The Collection editor properly shows the properties for the StatusBarProgressPanel only after the sample project has been compiled. Until then, it doesn't know about the StatusBarProgressPanel. In a real-world scenario you would probably compiled the StatusBarProgressPanel to a separate assembly and include a reference to it in your project.
To make it so you could specify the type of StatusBarPanel to add to the Panels collection you would have to provide an alternate UITypeEditor for the StatusBarPanelCollection class. Unfortunately, I'm not sure how (or if) you could actually associate this UITypeEditor with the Panel property.
|
|
|
|
 |
|
 |
Thank you for your work! I have been looking for it for a long time ..
|
|
|
|
 |
|
 |
I've been looking for something like this for a month or so but been unsatisfied with everything I've found. This looks more like something I've been itching to get my hands on. I hope it works out! Thanks man.
|
|
|
|
 |