473,466 Members | 1,439 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

My Method on Paint drastically effects my program GUI's performance

EARNEST
128 New Member
Hello everyone,
I would like to ask for your help, guys. For some reasons, if i include the following lines in my paint event handler of my picture box, the GUI acts very weird (as if it cannot "draw" all the controls, some of them are invisible or the program acts as if there is no threading). The reason is because I include those lines of code. But what is the real reason behind it? Is it because Paint event handler tries to re-paint the controls all the time or what?
Expand|Select|Wrap|Line Numbers
  1.         void panelGraphDynamic_Paint(object sender, PaintEventArgs e)
  2.         {
  3.             Point yAxis_Start = new Point(5, 8);
  4.             Point yAxis_End = new Point(5, 185);
  5.             Point xAxis_Start = new Point(5, 185);
  6.             Point xAxis_End = new Point(310, 185);
  7.  
  8.             graphDynamic = new My_Graph(
  9.                 panelGraphDynamic, 
  10.                 yAxis_Start, yAxis_End,
  11.                 xAxis_Start, xAxis_End,
  12.                 2, 1,
  13.                 107);
  14.  
  15.         }
  16.  
Expand|Select|Wrap|Line Numbers
  1.         public My_Graph(
  2.             PictureBox panelGraphDynamic, 
  3.             Point pointY_axis_Start, Point pointY_axis_End, 
  4.             Point pointX_axis_Start, Point pointX_axis_End, 
  5.             int axisBrushWidth, int graphBrushWidth,
  6.             int numberOfTrainingPairs)
  7.         {
  8.             panelGraphDynamic.Image = new Bitmap(panelGraphDynamic.Width, panelGraphDynamic.Height);
  9.             Image bmp = panelGraphDynamic.Image;
  10.             this.gfx = Graphics.FromImage(bmp);
  11.             this.solBrushAxis = new SolidBrush(Color.Black);
  12.             this.colorPenBlackAxis = new Pen(this.solBrushAxis, (float)(axisBrushWidth)); //brush
  13.  
  14.             this.pointX_axis_Start = pointX_axis_Start;
  15.             this.pointX_axis_End = pointX_axis_End;
  16.             this.pointY_axis_Start = pointY_axis_Start;
  17.             this.pointY_axis_End = pointY_axis_End;
  18.  
  19.             this.gfx.DrawLine(this.colorPenBlackAxis, this.pointY_axis_Start, this.pointY_axis_End); //Y axis
  20.             this.gfx.DrawLine(this.colorPenBlackAxis, this.pointX_axis_Start, this.pointX_axis_End); //X axis
  21.  
  22.             panelGraphDynamic.Image = bmp;
  23. }
  24.  
Before I used a panel to draw in, but I've realized it is a better and smarter thing to draw on an image that would be put in the picture box later. Also, it would be easier to save my graph as a picturebox(bitmap).
Thanks in advance for the explanation.
Feb 25 '10
77 6227
tlhintoq
3,525 Recognized Expert Specialist
Tell ya what... If you zip up the actual Visual Studio project and stick it in my iDisk I'll take a look later today.

http://public.me.com/tlhintoq
Mar 1 '10 #51
EARNEST
128 New Member
Done, thanks. It is a new project, only graph implementation. Decided to get my hands dirty with it, going to tackle it until its done, then move on back to my main project.
Kindly check /bytes/ folder
Mar 1 '10 #52
tlhintoq
3,525 Recognized Expert Specialist
Take a look at the updated project.

May I also suggest that even in your own quick test projects, it doesn't take that long to put a couple labels on the form for the controls, or to give the controls meaningful names?

trackBar1 is not as human-friendly as barStartX

When you start getting into groups of them it is far too easy to forget what is what or not recogonize a problem.

Expand|Select|Wrap|Line Numbers
  1. point NewStart = new Point(barStartX.Value, barStartY.Value);
  2.  
  3. // is easier to diagnose than
  4.  
  5. point NewStart = new POint (trackBar1.Value, trackBar4.Value);
Mar 1 '10 #53
EARNEST
128 New Member
OK in a moment. I was trying to update mine. What you think of this:
Expand|Select|Wrap|Line Numbers
  1.  
  2.         public void DrawAxis()
  3.         {
  4.             if (ShowAxis)
  5.             {
  6.                 bmp = new Bitmap(this.Width, this.Height); 
  7.                 this.gfx = Graphics.FromImage(bmp);
  8.  
  9.                 this.Image = new Bitmap(this.Width, this.Height);
  10.                 Console.WriteLine("SIZE: " + this.Size);
  11.                 this.BrushForAxis = new SolidBrush(Color.Black);
  12.  
  13.                 this.PenForAxis = new Pen(this.BrushForAxis, (float)(2));
  14.                 if (Y_Max == 0 || X_Max == 0)
  15.                 {
  16.                     Point y2 = new Point(5, this.Height - 10);
  17.                     Point x2 = new Point(this.Width - 10, this.Height - 10);
  18.                     Point y1 = new Point(5, 5);
  19.                     Point x1 = new Point(5, this.Height - 10);
  20.  
  21.                     this.gfx.DrawLine(this.PenForAxis, y1, y2);
  22.                     this.gfx.DrawLine(this.PenForAxis, x1, x2);
  23.                 }
  24.                 else
  25.                 {
  26.                     Point y2 = new Point(5, Y_Max);
  27.                     Point x2 = new Point(X_Max, Y_Max);
  28.                     Point y1 = new Point(5, 5);
  29.                     Point x1 = new Point(5, Y_Max);
  30.  
  31.                     this.gfx.DrawLine(this.PenForAxis, y1, y2);
  32.                     this.gfx.DrawLine(this.PenForAxis, x1, x2);
  33.                 }
  34.  
  35.                 this.Image = bmp;
  36.             }
  37.  
  38.         }
  39.  
Still working on it :) got excited
Mar 1 '10 #54
tlhintoq
3,525 Recognized Expert Specialist
Take a look at what I sent you, and see if your updates can be incorporated.
I think there are some things in there you can learn from.
Mar 1 '10 #55
EARNEST
128 New Member
Checked. It is a very interesting approach :) Thanks a lot.
I think there are some things in there you can learn from
yes indeed...Keep you updates when I add/change something or anything else.
Thanks for participation
Mar 1 '10 #56
EARNEST
128 New Member
Hello again, hope you're doing well.
Wanted to ask, how would I get the parameters of the "parent" control I extended during instantiation of my custom control or somehow automatically, meaning that if for my constructor I include the following lines:
Expand|Select|Wrap|Line Numbers
  1. GraphBox()
  2. {
  3.  bmpOfClass = new Bitmap(this.Width, this.Height);
  4. }
  5.  
would set the size based on the one of the picturebox in the designer class, instead of default values 100,50. Should I create a property that would by default call another pseudo-constructor setting width, height and other things, or there are some other better implementations?
Thanks, EARNEST.
Mar 2 '10 #57
tlhintoq
3,525 Recognized Expert Specialist
That code is making the size dynamically.
When you drag a new GraphBox onto a form, AND SIZE IT - that should be it.

Later when you run the program, and the new graphbox is created that will be 'this' used for 'this.Width' and 'this.Height'
Mar 2 '10 #58
EARNEST
128 New Member
Don't know if it was a hidden hint, but thanks.
Did following:
Expand|Select|Wrap|Line Numbers
  1.             this.SizeChanged += new EventHandler(GraphBox_SizeChanged);
  2.         }
  3.  
  4.         void GraphBox_SizeChanged(object sender, EventArgs e)
  5.         {
  6.             Console.WriteLine(this.Width);
  7.         }
  8.  
What do you think about it?
---
Update: Also, need to take care about default settings, otherwise I ll get "Object reference not set to an instance of an object. "
Mar 2 '10 #59
tlhintoq
3,525 Recognized Expert Specialist
That will report it to your console, if that is what you are trying to do.
Is that why you thought it wasn't the right size? Because the console window had old data? You can always put a couple labels on the form to report such data.
Mar 2 '10 #60
EARNEST
128 New Member
That will report it to your console, if that is what you are trying to do.
Is that why you thought it wasn't the right size? Because the console window had old data? You can always put a couple labels on the form to report such data.
Not sure if I got you, I always use console output to test if the system does what i want :)) silly old habit, actual code would be
Expand|Select|Wrap|Line Numbers
  1.         void GraphBox_SizeChanged(object sender, EventArgs e)
  2.         {
  3.             this.Image = new Bitmap(this.Width, this.Height); //image of the (this)picturebox
  4.             this.bmp = new Bitmap(this.Width, this.Height); //bitmap of the class
  5.             this.gfx = Graphics.FromImage(bmp); //graphics instance   
  6.         }
Mar 2 '10 #61
tlhintoq
3,525 Recognized Expert Specialist
Expand|Select|Wrap|Line Numbers
  1. void GraphBox_SizeChanged(object sender, EventArgs e)
  2.         {
  3.             this.Image = new Bitmap(this.Width, this.Height); //image of the (this)picturebox
  4.             this.bmp = new Bitmap(this.Width, this.Height); //bitmap of the class
  5.             this.gfx = Graphics.FromImage(bmp); //graphics instance   
  6.         }
You make a new image, then a new bmp, then a new Graphics context... and do what with them? What purpose do they serve?
Mar 2 '10 #62
EARNEST
128 New Member
there are other methods where those might be used (DrawAxis, DrawGraph etc)
Mar 2 '10 #63
tlhintoq
3,525 Recognized Expert Specialist
Right... But if you aren't going to use them at that specific point in time, you are just causing a lot of work for nothing.

SizeChanged happens for every pixel you change it, throughout the resizing drag. So you might want to make this happen only on the SizeChangeCompleted event, so it doesn't make 1000 new images for no purpose. Just do it one time at the end of the resize IF you are going to go ahead and complete the process by recalculating the graph.
Mar 3 '10 #64
EARNEST
128 New Member
Just do it one time at the end of the resize IF you are going to go ahead and complete the process by recalculating the graph.
Sorry, didn't quite understand what you meant...
First of all, are you saying that SizeChanged event would occur N times, for every changed pixel from 100,50, meaning if the new size is 150,50, it would occur 50 times? If yes, how come when I had console output, it displayed just once?
Also, did'nt get your point:
going to go ahead and complete the process by recalculating the graph.
And finally, should I just add
Expand|Select|Wrap|Line Numbers
  1. this.Image = new Bitmap(this.Width, this.Height); //image of the (this)picturebox
  2.             this.bmp = new Bitmap(this.Width, this.Height); //bitmap of the class
  3.             this.gfx = Graphics.FromImage(bmp); //graphics instance   
  4.  
To every method then? I added those lines of code to the SizeChanged event so it will be "there waiting for" any method that possibly would be invoked.
Mar 3 '10 #65
EARNEST
128 New Member
Following code:
Expand|Select|Wrap|Line Numbers
  1.                 this.gfx.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
  2.                 this.gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
  3.                 this.gfx.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
  4.  
  5.                 gfx.DrawLine(penForScales, 4f, 44f, 60f, 44f);
  6.                 gfx.DrawLine(penForScales, 4f, (float)(this.Y_end.Y - (5 * offset * 15)), 60f, (float)(this.Y_end.Y - (5 * offset * 15)));
  7.  
This would be called each item mouseclick event occurs. Somehow, the smoothmode makes the 2nd DrawLine get with each click "fatter", however the first DrawLine does not "change". Cannot understand why..., however, this solved the problem
Expand|Select|Wrap|Line Numbers
  1.                 gfx.DrawLine(penForScales, 4f, (float)(int)(this.Y_end.Y - (5 * offset * 15)), 60f, (float)(int)(this.Y_end.Y - (5 * offset * 15)));
  2.  
  3.  
Mar 3 '10 #66
EARNEST
128 New Member
New implementation of a graph. I will post it later on (or when I am finally finished with it, I shall create a new thread). I think my new implementation is more efficient then before. I draw axis, scales, labels etc in 1 picturebox, then I add 1 more picturebox inside the graphbox(picturebox) in between the axis, so I "forget" about the first parent control, and if i need to repaint or "reset" the actual graph, I ll just deal with it via my 2nd box, without invoking unnecessary methods that would cause a whole graphbox to re-adjsut, re-paint etc. What do you think about it?
However, I have 2 issues I am still trying to solve.
1. What .Image is for? And when should I add this.Image = bmp;? Or should I add it at all, since I still see all the drawing, without that line of code.
2. I would like to save as bitmap everything that is in my graphbox, however, when I request
Expand|Select|Wrap|Line Numbers
  1.  this.Image.Save("name.bmp")
, it saves everything, but the 2nd picbox inside of it (parent graphbox control that extends picturebox <- reminder how i implemented, just in case ). Why is that?
Thanks, EARNEST.
Mar 4 '10 #67
tlhintoq
3,525 Recognized Expert Specialist
You know a PictureBox actually holds two images, right?
A background image and its regular .Image.

It might be less complicated to just use two images instead of two complete PictureBox controls. The background can be whatever you need, and the axis, lines and so on would 'overlay' that by being on the primary .Image (which is the foreground image)
Mar 4 '10 #68
EARNEST
128 New Member
Did not know that :) Thanks a lot, I will look into it
Mar 4 '10 #69
EARNEST
128 New Member
Hm...it looks a bit weird.
Expand|Select|Wrap|Line Numbers
  1.  
  2.         public void DrawGraph_Dynamic(int _yVariable)
  3.         {
  4.  
  5.             if (condition)
  6.             {
  7.                 bmp2 = new Bitmap(this.Width, this.Height);
  8.                 this.BackgroundImage = new Bitmap(this.Width, this.Height);
  9.                 this.gfx2 = Graphics.FromImage(bmp2);
  10.  
  11.                 this.count = 1; //reset counter to 1
  12.                 this.tempX = this.Y_start.X + count; //temp adjustements
  13.                 this.x2 = this.Y_start.X + count; //reset position of X
  14.             }
  15.  
  16.             this.gfx2.DrawLine(penForGraph, tempX, tempY, x2, y2); //actual graph drawing
  17.             this.tempX = x2; //coordinates for smooth graph connections
  18.             this.tempY = y2; //coordinates for smooth graph coonections
  19.             this.BackgroundImage = bmp2;
  20.             this.Image = bmp;
  21.         }
  22.  
1. gfx is for axis, scale and other things, fromimage bmp. when the last thing is drawn on the image, i set this.Image = bmp;
2. Second point, the code looks a bit "weird". Or I am mistaken?
3. Is it the right way I used the background image? gfx2, bmp2 are for graph drawings.
4. If i won't put in the end .BackgrnImage and .Image, the graph would'nt be painted
Mar 4 '10 #70
EARNEST
128 New Member
Expand|Select|Wrap|Line Numbers
  1.         public void DrawGraph_Dynamic(int _yVariable)
  2.         {
  3.  
  4.             // TAKE INTO ACCOUNT PROPORTIONS
  5.             count++;
  6.             x2 = (float)(this.X_start.X + count);//incrementing X
  7.             y2 = (float)(this.Y_end.Y - _yVariable * offset) - 1; //decreasing value of Y in respect to offset value and errors number(var_Yaxis)
  8.  
  9.             if (tempX == 0 && tempY == 0) //fixes the crazy jump in the beginning
  10.             {
  11.                 tempX = x2; //smooth start
  12.                 tempY = y2; //smooth start
  13.             }
  14.             if (count >= this.X_end.X - this.X_start.X)
  15.             {
  16.                 //NOT GOOD !->
  17.                 string bmp_filename = "graph.bmp";
  18.                 this.Image.Save(bmp_filename);
  19.                 this.BackgroundImage.Save("graph_2.bmp");
  20.                 //<-!
  21.                 this.bmp_BACKGROUND = new Bitmap(this.Width, this.Height);
  22.                 this.BackgroundImage = new Bitmap(this.Width, this.Height);
  23.                 this.gfx_BACKGROUND = Graphics.FromImage(bmp_BACKGROUND);
  24.  
  25.                 this.count = 1; //reset counter to 1
  26.                 this.tempX = this.Y_start.X + count; //temp adjustements
  27.                 this.x2 = this.Y_start.X + count; //reset position of X
  28.             }
  29.  
  30.             this.gfx_BACKGROUND.DrawLine(penForGraph, tempX, tempY, x2, y2); //actual graph drawing
  31.             this.tempX = x2; //coordinates for smooth graph connections
  32.             this.tempY = y2; //coordinates for smooth graph coonections
  33.             this.BackgroundImage = bmp_BACKGROUND;
  34.             this.Image = bmp_FOREGROUND;
  35.         }
  36.  
I cannot save as ONE bitmap file with foreground and background images.
Mar 4 '10 #71
tlhintoq
3,525 Recognized Expert Specialist
I cannot save as ONE bitmap file with foreground and background images.
When you are ready to save, just merge one photo with the other, then save the result.
Mar 4 '10 #72
EARNEST
128 New Member
OK, thanks, I ll try to do that.
Also,
1. gfx is for axis, scale and other things, fromimage bmp. when the last thing is drawn on the image, i set this.Image = bmp;

3. Is it the right way I used the background image? gfx2, bmp2 are for graph drawings.
4. If i won't put in the end .BackgrnImage and .Image, the graph would'nt be painted
of previous post, i just left it liek that, since it works, but is it the right way? is it efficient?
---------
Update. Going to bed now, before I go, if there are some other readers here, apart from me and mr/ms tlhintoq :) here is my "draft" merge, going to work on it tomorrow.

Expand|Select|Wrap|Line Numbers
  1.   PictureBox tempToMerge_picBox = new PictureBox();
  2.                 tempToMerge_picBox.Image = new Bitmap(this.Width, this.Height);
  3.                 Image tempToMerge_img = new Bitmap(this.Width, this.Height);
  4.                 Graphics tempToMerge_gfx = Graphics.FromImage(tempToMerge_img);
  5.                 tempToMerge_gfx.DrawImage(this.Image, new Point(0, 0));
  6.                 tempToMerge_gfx.DrawImage(this.BackgroundImage, new Point(0, 0));
  7.                 tempToMerge_picBox.Image = tempToMerge_img;
  8.                 tempToMerge_picBox.Image.Save("tempToMerge_IMAGE.bmp");
  9.  
Mar 4 '10 #73
EARNEST
128 New Member
Expand|Select|Wrap|Line Numbers
  1. this.gfx_FOREGROUND.DrawImage(this.BackgroundImage, new Point(0,0)); 
, however, I would need to re-paint the axis, scales, labels etc, when the graph exceeds the X-axis limit, I'd need to reset it and re-paint background, however, in this case, I'd need to "reset" foreground also, since I drew an image on it.

Less lines of code + invoking methods again VS previous method. What do you think?

---
Update:
Expand|Select|Wrap|Line Numbers
  1. this.gfx_BACKGROUND.DrawImage(this.Image, new Point(0,0)); 
  2.  
  3.                 string bmp_filename = "graph.bmp";
  4.                 this.BackgroundImage.Save(bmp_filename);
  5.  
I think this one is even better than 2 of those.
Mar 5 '10 #74
tlhintoq
3,525 Recognized Expert Specialist
I think I got lost about 3 posts ago. If you are getting results you like, then it's good.
Mar 5 '10 #75
EARNEST
128 New Member
Yeah i think it works now. I am done with graphbox. I want to add it to the toolbar, would it be possible without importing the .cs class all the time to any project?
Mar 5 '10 #76
tlhintoq
3,525 Recognized Expert Specialist
Yep. What I did actually was make a project that holds all my custom tools and classes. It is my own namespace. That way instead of calling
System.IO.File.Delete
I call
tlhintoq.IO.File.Delete (which resets all the attributes before trying to delete)

Set up the project as a DLL library. Build it. Then in your Toolbox pallet make a new tab and 'Choose Items" (both from right-click menu)
Mar 5 '10 #77
EARNEST
128 New Member
Ok, thanks a lot. You helped me a lot during this "small project" :)
For now I am set, maybe later on I will try to add more functions or optimized/re-arrange my code.

If anyone is interested in my graphbox control, write it here, and I will upload it ASAP.
Mar 5 '10 #78

Sign in to post your reply or Sign up for a free account.

Similar topics

5
by: Zach | last post by:
This is all on linux using jdk1.3. My application is written in AWT, no swing. The application requires running it on the host machine and tunneling the GUI back to a client. I've been doing...
2
by: DraguVaso | last post by:
Hi, In the override of the Paint-method of a DataGridTextBoxColumn I want to show an image with BitBlt, to see what I can gain there on performance. The problem is: It doesn't show me the image...
4
by: Franck | last post by:
Hello, Sorry if that question has already been raised... I'm looking for the exact equivalent of Java paint(Graphics g) method in c# in order to paint a specific component and all its children...
1
by: Benny Raymond | last post by:
I'm trying to adjust the length of the strings being drawn, as well as some effects depending on what item is actually being drawn. I tried doing the following, but the paint event never runs: ...
5
by: Stig | last post by:
I would like to output the sequence of method calls from a running c# applcaition, but I don't want to add Debug.trace calls at the entry and exit points in each an every methods. Does there...
29
by: 63q2o4i02 | last post by:
Hi, I'm interested in using python to start writing a CAD program for electrical design. I just got done reading Steven Rubin's book, I've used "real" EDA tools, and I have an MSEE, so I know what...
94
by: smnoff | last post by:
I have searched the internet for malloc and dynamic malloc; however, I still don't know or readily see what is general way to allocate memory to char * variable that I want to assign the substring...
12
by: Matt Bitten | last post by:
I've got a wxPython program that needs to do some drawing on a DC on a regular basis, whether or not a paint event happens. I know how to make a ClientDC to do the drawing in, and I know what...
0
by: Leo Lee | last post by:
Hi, I think I have already solved this problem while I am digging into the installation sources. I found this: C:\Python25\Lib\site-packages\py2exe\samples\singlefile\gui\setup.py # Requires...
4
by: lilyumestar | last post by:
I have project I have to do for class. We have to write 4 different .java files. Project2.java HouseGUI.java House.java HouseSorting.java I already finish House.java and I need to work on...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.