I have a relatively simple windows application. It uses about 15 controls.
My constructor method looks like this:
public Form1()
{
InitializeComponent();
this.Paint += this.Teken;
}
My Teken method (simplified) looks like this:
private void Teken(object o, PaintEventArgs pea)
{
if (start)
{
if (comboBox1.Text == "Basic")
Bitmaps.DrawBitmap1(pea.Graphics, bitmapsize, max);
}
}
My DrawBitmap1 method sets every pixel a certain color and then draws a bitmap using the Graphics.DrawImage method.
After the bitmap is drawn, the controls become really laggy and it takes more than a second to select text in a textbox. The main form just gets really slow.
I can understand the bitmap to be drawn slowly but I can’t understand this.
Is there a simple solution to my problem?
EDIT:
Here’s the Drawbitmap1 code:
public static void DrawBitmap1(Graphics gr, int bitmapsize, int max)
{
Bitmap bitmap1 = new Bitmap(bitmapsize, bitmapsize);
for (int x = 1; x < bitmapsize; x++)
{
for (int y = 1; y < bitmapsize; y++)
{
int mandelnumber = CalculateMandel(x,y)
if (Form1.mandelnumber == max)
bitmap1.SetPixel(x, y, Color.Black);
else if (Form1.mandelnumber %2 == 0)
bitmap1.SetPixel(x, y, Color.White);
else
bitmap1.SetPixel(x, y, Color.Black);
}
}
gr.DrawImage(bitmap1, 50, 100);
}
mandelnumber is a variable calculated in another part of the program.
EDIT2:
I’ve run a profiler and it seems that the method CalculateMandel() doesn’t stop running after it’s been through every pixel of the bitmap. How is this possible?
EDIT3:
Turns out the DrawBitmap1 function is called again when hovering over textboxes or buttons. How is this possible, I don’t have any hover events, not even TextChanged events..
This is wrong, it will call your
Tekenroutine every time your app needs repainting; when you open your window, when you resize your window, when you change focus, move another window, get a tooltip, change resolution or themes, practically all the time. In fact, about the only timeTekenis not called is whenCalculateMandelis finished and you need to show the results. You never callInvalidateso you are never alerted when you need to draw your results.Because you are specifically telling it to recalculate everything in your bitmap every time anything changes in your U.I.; over and over and over again. Unless only your bitmap changes, then you don’t tell it to repaint. Completely backward. This will also lock up your U.I. as you are uselessly recalculating your bitmap even if it doesn’t need redrawing.
But something else does; perhaps a tooltip. And you have told your app to call
CalculateMandel()every time anything in your app U.I. (except your bitmap) changes.The problem is you have two totally separate things going on; your app needs to repaint the U.I. when something changes, and you have a calculation (
CalculateMandel()) that you want to update the U.I. when it’s done. These are separate events and you must handle them separately.First, get rid of
this.Paint += this.Teken;; that’s causing your problems and will not do what you want.Second, create a
BackgroundWorkerthat callsCalculateMandel()in itsDoWorkevent and in yourProgressChangedevent returns the completed bitmap then callsyourWindowOrPanelOrWhatever.Invalidate()to redraw the new data.