|
Call Invalidate() on the control. That will post a request for a repaint, but if you really need an immediate repaint you should call Update() after calling Invalidate(). Note, you can also call Refresh(), which basically calls those two methods for you.
|
|
|
|
|
First, thanks for your help. I did what you suggested, and it did solve the repaint issue. Now I can see the lines been updated.
Now, the problem is that the screen is getting erased before the new point is drawn (as it would be expected from your description), but I need to keep the points already drawn and add the new point to the end of the line, forming a continuous curve. Then, when that line reaches the end (right border) of the canvas, I should send the carrier back to the begining (left border) and continue drawing, with a blank region in front of it, as if there was an eraser in front of the current point.
Thanks again!
|
|
|
|
|
ZeAugusto wrote: as if there was an eraser in front of the current point.
No erasing but the graphics system does not remember what you previously drew, you have to do that and draw everything in the window (or invalid region) during a paint event. Last modified: Wednesday, June 21, 2006 12:58:57 PM --
|
|
|
|
|
Rather than invalidating the control, call yourCustomControl.CreateGraphics() to get a Graphics object which will render onto your control surface. Then perform the painting in a separate method (not the Paint event handler). That new method will draw only the new point(s) and not erase the other ones. You'll probably want to have your Paint event handler call into this new method so that the rendering logic is factored properly.
Josh
|
|
|
|
|
I think a proper way is using double-buffering. You maintain a graphical buffer and you draw to the buffer. Whenever you want to update the screen, copy the buffer to the screen. There are two approaches to the buffer drawing:
1) If you just add (not erase, not change) contents to the screen, grab the graphic object and draw to the buffer on the top of existing contents.
2) If you erase or change any existing contents on the screen, you need to repaint the buffer's background and then redraw it completely.
I've assumed you have fair understanding about how Windows graphics work. If you need more guidance, drop a line.
Best,
Jun
|
|
|
|
|
Thanks for all the replies!
As I didn't know how to add content without refreshing the whole object, I ended up implementing a mixture of your suggestion with Josh's and Led's ones. I used the GraphicsPath class instead of just drawing single line segments, adding the newly calculated points to it, and then redrew the entire path at every Refresh() call (which happens whenever I add a point to the graph, every 40 ms). At the end of the line, I clone this path to a second one, and reset the first. This way, I work with two paths, the most recent one "above" the oldest, and redraw both when a new point is added.
To solve that "erasing" part I mentioned before, I used a little trick. I draw a black rectangle (because the background of the graph region is also black) between the two paths, and resize it so that it is always a few pixels wider than the top path. This way, it looks like there is an eraser in front of the line being drawn. It's quite similar to what I've already done in Flash.
But I have a new question, though. As far as I draw all these objects every 40 miliseconds, I wonder if I might experience some performance issues. The application is intended to support an average of 5 to 10 simutaneous instances of this control, so that might become a problem... Or am I just being paranoid because of my Flash experience?
Thanks,
Ze
|
|
|
|
|
ZeAugusto wrote: I wonder if I might experience some performance issues.
Can't say for sure. Keep your fingers crossed.
ZeAugusto wrote: The application is intended to support an average of 5 to 10 simutaneous instances of this control, so that might become a problem...
It also depends on how large (portion of screen taken) your control is.
Best,
Jun
|
|
|
|
|
|
Hi,
My opacity control causes a really bad BLACK flicker after the opacity is initially decreased via the trackbar control. Any ideas on how to get rid of the black flicker would be greatly appreciated.
PS: I tried calling Invalidate and ReDraw after Opacity is adjusted with no luck.
Some of the code...
//
// trackBar1
// Code located on the fader (opacity) control
this.trackBar1.Location = new System.Drawing.Point(26, 14);
this.trackBar1.Maximum = 100;
this.trackBar1.Minimum = 10;
this.trackBar1.LargeChange = 5;
this.trackBar1.SmallChange = 5;
this.trackBar1.Name = "trackBar1";
this.trackBar1.Size = new System.Drawing.Size(220, 45);
this.trackBar1.TabIndex = 0;
this.trackBar1.TickFrequency = 10;
this.trackBar1.TickStyle = System.Windows.Forms.TickStyle.Both;
this.trackBar1.Value = 100;
this.trackBar1.MouseUp += new
System.Windows.Forms.MouseEventHandler(this.TrackBar1_ValueChanged);
private void TrackBar1_ValueChanged(object sender, System.EventArgs e)
{
if (_OpacityChanged != null)//run event
{
_OpacityChanged(this.trackBar1.Value);
}
}
// Code located on the main form. User clicks button to bring up control
private void faderControl_Click(object sender, EventArgs e)
{
FaderControl myFaderControl = new FaderControl();
myFaderControl._OpacityChanged += new
FaderControl.UpdateOpacity(OnOpacityChanged);
myFaderControl.ShowDialog();
}
private void OnOpacityChanged(double OpacityValue)
{
double newOpacityValue = OpacityValue / 100;
this.Opacity = newOpacityValue;
}
|
|
|
|
|
Are you setting styles for double buffering and all painting in wmpaint?
|
|
|
|
|
Mike, Thanks for your reply!
I am setting all controls that go on the form to this.DoubleBuffering = true.
How do I set all painting to wmpaint? I'm not familiar with this property.
Tom
|
|
|
|
|
SetStyle( ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
|
|
|
|
|
Mike,
Thanks again, I'm using something similar. On all forms and controls I envoke...
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint |
ControlStyles.OptimizedDoubleBuffer, true);
Still Ugly Black Flicker occurs!
Tom
|
|
|
|
|
Cubzfan wrote: On all forms and controls I envoke
No. In your custom control. FaderControl is your own custom control right? That's what is flickering yes?
|
|
|
|
|
Mike,
No, the form the control is changing the Opacity flickers black when the control is initially taken from the default full opaque setting to any decrease setting. The control works fine after that. If you increase or decrease the parent forms opacity with the child control it changes as it should unless the control is once again set all the way to the right (max setting the parent form to full opaqe) and you decrease again the black flicker happens again.
Hope this helps clear things up???
I really appreciate the help!!
|
|
|
|
|
So you are working on a Custom Control, you are changing the opacity of a .NET Form. Yeah I have no idea what might help with that. See Dustin Metzgar's post maybe it will help.
|
|
|
|
|
Which OS are you using? I noticed having flicker problems in Win 2000, but everything was fine in XP.
Logifusion[^]
|
|
|
|
|
Dustin,
Thanx for the reply! I am using XP.
|
|
|
|
|
Damn. Thought maybe it was an easy solution. In one of the projects I worked on, the help->about dialog box would fade in using the opacity control. In 2000, it often had problems and would sometimes appear black until it got to an opacity of 1.00. The only thing I can really suggest is that you try setting the opacity in the Form's thread. It looks like you have a separate dialog box that you use to set the main form's opacity. I think that means there is one thread for your dialog and one for your main form. Maybe you can try using Invoke and a delegate to set the opacity in the main form's thread.
I'm not sure if it works or not. We ended up just saying "Eh, good enough."
Logifusion[^]
|
|
|
|
|
Dustin,
This gets better! I disabled the opacity control and tried setting the forms opacity to 0.50 when the form is initialised. When the form pops up, same thing black flicker then form and new opacity are what they are suppose to be.
Very frustrating, but I will prevail!!
Thanx again,
Tom
|
|
|
|
|
Tom,
I was glancing several times at this thread today, and something about the "black flicker" was sounding familiar. Anyway, I think I've figured out a solution, so I'll take a crack at it.
Slight disclaimer: I've only done one test with this, and I think it works, but I cannot be sure. Please let me know if it doesn't work.
Basically the solution is this: don't use the OptimizedDoubleBuffer and AllPaintingInWmPaint styles for the form which you are making more or less opaque. I was reading a short article on another site about Transparent Windows Forms Controls (you can look at it here[^] - some of the images are broken, but the article text is all that matters). On that page, the author notes that, when making truly transparent controls, you cannot use double buffering, because "The memory bitmap which is provided to your code has an opaque background and does not allow the carefully retained parent pixels to show through". This makes sense when you think about how double-buffering is done: basically, you are drawing to a buffer which is never displayed, and so I would imagine there is no previously drawn pixels on that buffer (which is necessary for transparency, because you need your pixels to be blended with the pixels which are behind them).
Give that a try on your Form, and see what happens. That is, in your Form's constructor (the one whose opacity you are changing) take out the two styles OptimizedDoubleBuffer and AllPaintingInWmPaint . I'm not sure why AllPaintingInWmPaint does not work properly, but in my test it gave a black flicker when it was set, even without the double-bufferring. I suspect it has to do with OnPaintBackground not being called when that style is set, and therefore the proper blending does not occur with the form background.
As a side note, I can make the background flicker black when I minimize and then restore my form. You did not mention this before, but I thought it might help to mention it so that you can check if your code produces the same effects as I have been throughout.
Hope that helps!
Sincerely,
Alexander Wiseman
|
|
|
|
|
Alexander,
Thanx for your reply! I tried taking both the OptimizedDoubleBuffer and AllPaintingInWmPaint from the form I am changing opacity on... no luck. Just for grins I then commented out all code for all controls disabling those methods and still the same ugly black flash.
Thanks,
Tom
|
|
|
|
|
Tom,
I tried a few more things, and did a few more Google searches, and here is what I came across (which, I may add, makes much more sense than the double-buffer issue that I related in my previous post). This is on a CP article message board (you can see the article here[^]):
The question
"I like this control alot but when I close my form, all controls on it flicker for a blink of an eye to black and then the fade begins. any suggestions to fix it?"
That looks like your problem exactly. Here is the response:
The response (from the article author)
"Short version:
Check if you are using a transparency key. If not, try and set one. Pick a color that won’t affect your program such as lime green, or some other ugly color that is not used by anything on your form.
Long version:
If it’s the same flicker as one I have seen before, than it has to do with a bug in WinForms and how it deals with transparent windows. WinForms is in fact just a wrapper to the Windows API. When dealing with opacity, WinForms will use a Windows API to convert your form to what is know as a layered window.
“Using a layered window can significantly improve performance and visual effects for a window that has a complex shape, animates its shape, or wishes to use alpha blending effects.” – MSDN
However, WinForms does not make a window a layered window until it feels it is necessary. The flicker you are seeing is WinForms trying to convert a non layered window into a layered one.
The reason why setting a transparency key works is because WinForms will force any window with a transparency key to be of the type layered. Set the transparency key at design time and at runtime the window will always be a layered window. With no need to convert, the flicker goes away.
-Mike."
It seems from his response that the black flicker you see is the changing of the window from a normal window to a layered window. His suggested solution is to set the transparency key (to some color you do not use on the form) which will force the window to be created as a layered window. This should fix the flicker when you first change the opacity.
I gave this a try and it worked well to remove the black flicker on using the sliding control first and on minimize and maximize. However the black background appears when you first load the form, and it looks like a slight flicker to me. This, I think, you probably will not be able to get rid of, it's just that on faster systems you might not see it at all.
FYI, I tried setting double-buffering on with this solution and it didn't seem to make a difference one way or another, so you can probably use it anyway.
Give this a try and let me know the outcome, I'm very interested in this problem!
Sincerely,
Alexander Wiseman
|
|
|
|
|
Alexander,
Once agin thanx! I am now at home and will check in the morning (8:00 am CST). I really appreciate your effort. I have been trying to google the problem all day! I am only checking now at home because I think I have some kind of obcessive compulsive disorder when it comes to troubleshooting!
I'll keep you in the loop tomorrow!
Thanx again,
Tom
|
|
|
|
|
Alexander,
Tried setting the trans key to lime green with no luck. It did help a little because now it only does the black flicker when the opacity is initially changed. It also appears more resources are being used (slower). I'm going to continue the search.
Thanx,
Tom
|
|
|
|
|