|
Wise men have already spoken. So, no need to answer the question asked about disposing.
Your suggestion is right about doing the paint part in Form.Paint event. However, I don't see anything wrong in doing it in Button_Click for learning purposes. Doing all drawing during paint may become an herculean task.
I prefer doing my drawing on a bitmap at different occasions and draw the bitmap during Form.Paint. This imitates double buffering and saves from doing any calculations that may be required in Form.Paint every time the form is painted.
|
|
|
|
|
While Pete had explained that dispose should be used, he hadn't explained why, or how to best do it. I felt it worth a (slightly) more detailed response.
The only problem with drawing in the Click event for learning purposes is that it can confuse more than elucidate - look at the number of "I drew it and it disappeared" questions we get. Starting off with drawing into the Paint event, with an existing Graphics context just makes it a bit easier for beginners. They can them be introduced to the concept of graphics contexts for other objects.
I have learnt that you can not make someone love you, all you can do is stalk them and hope they panic and give in.
Apathy Error: Don't bother striking any key.
|
|
|
|
|
Hey, lemme say sorry for not writing in the correct grammar. What i said was:
Som wrote: Wise men have already spoken. So, no need to answer the question asked about disposing.
and what i meant
Wise men have already spoken. So, I do not need to answer the question asked about disposing.
he he he. I was talking about both of you.
I do not deny that writing in Paint event is incorrect. I am only saying that it is not necessary and shouldn't be considered as a norm. Thats all.
By the way, our so long discussion might be confusing the poor guy who wrote the code for the first time
|
|
|
|
|
He wasn't talking about me. He said wise. Good explanation though and you might want to consider posting it as a tip/trick so that it can be easily linked to in response to other questions.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
Som Shekhar wrote: I don't see anything wrong in doing it in Button_Click for learning purposes
For the most part yes, but many beginners get the idea that that is a "best practice" and never progress -- much like all the books that show data access in click handlers.
|
|
|
|
|
I'm not sure it's a big deal. This seems to work fine:
private void button1_Click(object sender, EventArgs e)
{
Random rnd = new Random((int)(DateTime.Now.Ticks % int.MaxValue));
for (int i = 0; i < 100000; i++)
{
Graphics g = this.CreateGraphics();
g.DrawEllipse(Pens.Blue, new Rectangle(rnd.Next(0, 50),
rnd.Next(0, 50), rnd.Next(55, 100), rnd.Next(55, 100)));
}
}
I'm sure it's not a bad idea to manually dispose of the Graphics object, but I'm not sure it's entirely necessary to make sure one does so.
|
|
|
|
|
Don't forget that the Graphics object (along with Pens, Brushes, etc.) do not just allocate unmanaged memory - they also allocate GDI handles, which are a limited system resource. If you do not release them, there is no guarantee that your software will continue to work in all environments. Using Dispose on all applicable objects is considered good practice because it does reduce the chances of unpredictable failures now or in the future.
On a side note: If your code executed only once a second, it would execute 100000 Graphics object creations in just over a day. How long would it last before it started to get problems? I dunno; that is the fun of memory leaks!
I have learnt that you can not make someone love you, all you can do is stalk them and hope they panic and give in.
Apathy Error: Don't bother striking any key.
|
|
|
|
|
OriginalGriff wrote: If your code executed only once a second, it would execute 100000 Graphics object creations in just over a day.
Did you see the for loop? That's how many it creates per button click. There was not much of an increase in memory usage.
OriginalGriff wrote: they also allocate GDI handles, which are a limited system resource
That might be a valid concern.
|
|
|
|
|
aspdotnetdev wrote: Did you see the for loop?
I did - but I've only had one cup of coffee this morning, and explained what I meant badly.
What I meant was: In the real world, your code would not necessarily sit on a button click, but would react to what else is going on. If you had your drawing code in a method that was executed frequently (by a timer update, or other external event) then at a rate of one execution per second, 100000 Graphics object creations would happen in just over a day.
I have learnt that you can not make someone love you, all you can do is stalk them and hope they panic and give in.
Apathy Error: Don't bother striking any key.
|
|
|
|
|
Hi Roger,
All the advice you've been given is correct. I just thought I'd put my 2c in...
Graphics objects, Pen s & Brush es should be disposed of unless they are available already as a property/parameter. If you draw in OnPaint you can use the e.Graphics property and there is no need to dispose it. If however you are drawing elsewhere and using CreateGraphics then you should dispose of it either explicitly, or implicitly by using a using block. The same for Pen s and Brush es, if you are using the System ones as in your code then there is no need to dispose, but if you create your own then you must dispose of them.
If it's a one off drawing I normally drop it into the OnPaint handler as has been suggested. If it's likely to be used several times I create a class/struct with a Draw method that takes any useful parameters including a Graphics instance and call that from OnPaint . Triggering OnPaint is easily done by calling Invalidate .
Something like this gives you a reusable Rectangle/Ellipse that can be drawn easily and no memory leaks.
using System;
using System.Drawing;
using System.Windows.Forms;
public partial class FormFlowCalcs : Form
{
private RectangleWithEllipseUnfilled rectangleWithEllipseUnfilled;
private Point rectangleWithEllipseUnfilledLocation;
private bool rectangleWithEllipseUnfilledVisible;
public FormFlowCalcs()
{
InitializeComponent();
Size = new Size(800, 600);
rectangleWithEllipseUnfilled = new RectangleWithEllipseUnfilled(
Color.Black, Color.Red, new Size(200, 200));
rectangleWithEllipseUnfilledLocation = new Point(200, 200);
rectangleWithEllipseUnfilledVisible = false;
}
private void buttonToggle_Click(object sender, EventArgs e)
{
rectangleWithEllipseUnfilledVisible = !rectangleWithEllipseUnfilledVisible;
Invalidate();
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (rectangleWithEllipseUnfilledVisible)
rectangleWithEllipseUnfilled.Draw(rectangleWithEllipseUnfilledLocation, e.Graphics);
}
}
public struct RectangleWithEllipseUnfilled
{
private Color ellipseColor;
private Color rectangleColor;
private Size size;
public RectangleWithEllipseUnfilled(Color ellipseColor, Color rectangleColor, Size size)
{
this.ellipseColor = ellipseColor;
this.rectangleColor = rectangleColor;
this.size = size;
}
public Color EllipseColor
{
get { return ellipseColor; }
}
public Color RectangleColor
{
get { return rectangleColor; }
}
public Size Size
{
get { return size; }
}
public void Draw(Point location, Graphics graphics)
{
Rectangle drawBounds = new Rectangle(location, size);
using (Pen ellipsePen = new Pen(ellipseColor))
{
graphics.DrawEllipse(ellipsePen, drawBounds);
}
using (Pen rectanglePen = new Pen(rectangleColor))
{
graphics.DrawRectangle(rectanglePen, drawBounds);
}
}
}
DaveIf this helped, please vote & accept answer!
Binging is like googling, it just feels dirtier. (Pete O'Hanlon)
BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)
|
|
|
|
|
Hi Roger,
I agree with what the others have said. And I add an example[^] that contains the relevant bits.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
Now I remember why I gave up trying to do any graphics work when Windows came out.
"A Journey of a Thousand Rest Stops Begins with a Single Movement"
|
|
|
|
|
Really? I don't find it hard at all, and Windows does a lot of things for you. You don't have to care about windows being partly hidden, getting uncovered, minimized, etc. It will repaint for you, assuming you did it right to start with.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
Hey Luc,
Is there any Graphics Library available for .Net which does more than what GDI+ does? I mean something that takes care of some advanced functions like layering?
I have an interest in printing multiple png images with transparency, being able to drag and drop them. Also, having multiple layers like in Adobe Photoshop?
Ofcourse I mean open source/free.
Som
|
|
|
|
|
I'm not experienced with any additional library, I tend to write the code I use myself. Mostly from reading forums like this one, I must warn you transparancy is a bit tricky in Windows.
You may want to look to some of the graphics articles at CodeProject; and then there is GIMP which could inspire you.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
GIMP is what drove me to try drawing in Windows.
"A Journey of a Thousand Rest Stops Begins with a Single Movement"
|
|
|
|
|
You might be able to do something with the Netron library available here[^].
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
I tried a little of that a while back, and found it not to be as straight-forward as I had hoped. I only needed to draw some lines and I got it working.
|
|
|
|
|
Then don't stop; the first line is the hardest
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
naah.. the hardest part is to fight flickering
when anything u do in windows doesn't work
|
|
|
|
|
The hardest part was keeping them where I want them as the underlying control scrolls, horizontally and vertically.
|
|
|
|
|
Just don't go one toke over the line.
|
|
|
|
|
I'm stuck on a previous problem that I posted a week or so ago (Please let me know if it is considered rude to post a new thread in this case)
I have a dataGridView that is bound to table1 in dataset1. I have changed the column type for column1 to a comboBox and have populated the collection with instances. Let's say 1, 2, and 3.
column2 is also a comboBox, but its instances need to be driven by column1. For '1' in column1, column2 would allow 11,12,13 and for '2' in column1, column2 would allow 21,22,23.
One suggestion was to create another dataTable in dataset1, and bind column2 to the new datatable using another bindingSource and then filter.
I went ahead and created another dataTable and edited the second column in the dataGridView to have the DataSource as bindingSource2 and the DisplayMember as column1 (the first column in dataTable2) (while this may not make sense at first glance, my objective was to manually populate data in dataTable2, column1 and then make sure the comboBox in column2 in dataTable1 would populate with dataTable2 values). But, this did not work.
Would it be easier here to create (3) ILists (IList1, IList2, IList3) each of which contain i1, i2, i3 for each list and then populate the comboBox in column2 of dataTable1 based upon the selection made in column1?
Do I need to look at the second dataTable option a bit more closely?
Thanks.
|
|
|
|
|
Firstly it most definitely NOT rude to repost after such an interval.
Secondly a question. Will your DataGridView only have one row or will it have, possibly, many rows where the user can perform this operation differently on each row? e.g. user selects 2 on row1 combo1 and selects 1 on row2 combo1 and so on.
If it is one row then perhaps a DataGridView is not the right option.
If it is more than one row then take a look at the links provided in DataGridView FAQ[^]. A possible solution is in Appendix A item 18 of the first one. There may also be a sample in the second link, I haven't got round to examining that yet.
Good luck!
Henry Minute
Do not read medical books! You could die of a misprint. - Mark Twain
Girl: (staring) "Why do you need an icy cucumber?"
“I want to report a fraud. The government is lying to us all.”
|
|
|
|
|
Thanks Henry.
Henry Minute wrote: Secondly a question. Will your DataGridView only have one row or will it have, possibly, many rows where the user can perform this operation differently on each row? e.g. user selects 2 on row1 combo1 and selects 1 on row2 combo1 and so on.
It will have many rows where the user can add additional devices. For example, they will have a device with a S/N 123. That device can connect to another device with S/N 234 (so now there are two columns). My challenge is to have a third and fourth column which is what this thread is about. There will be a collection in column 4 from which they can select. This will be read only. Going back to the original post, if they select '1' in column 3, they can only select '11', '12', or '13' in column 4. Again, read only. There can be several rows in the dataGridView.
Appendix A, 18 indicates pulling data from two tables. In this case, I am writing the data to a .xml file as there won't be a large amount of data. Therefore, there is only one table to speak of. Since column 4 is read only, it doesn't seem to make sense to have another .xml file for a table that just has a limited and fixed amount of data. I'm a novice, but I want to lean towards an IList, but I'm a novice.
I'm still going over this document (thanks a lot by the way, it's great for coming up to speed more quickly on dataGridView), but wanted to respond in case I was headed on a wild goose chase.
Thanks, Mike
|
|
|
|
|