.NET Forum / .NET Framework / Compact Framework / December 2005
Event subscription and form reference - Suffering fundamental misunderstanding
|
|
Thread rating:  |
Steve Howard - 29 Dec 2005 17:02 GMT [Frustrated beginner alert!!]
I am trying to work out how to subscribe to a form's Close event. When this form closes, I want my main form (hence my whole application) to close.
This article is supposed to explain, in simple terms, about event subscription, but somehow I am just not getting it at all - http://www.codeproject.com/csharp/eventdelegates.asp
My attempts at trying to fudge my own code (before I found the above article) ended in numerous dead ends where (I think) I needed to get a reference to a form, because trying to reference a form directly always failed to compile. It seems that I have not found, or have flat misunderstood how to successfully glean and hold a reference to a form.
From using other tools I get the principle of, say, a variable that holds actual data and, say, an Array that might contain references to data, not the actual data itself. But it seems I am totally missing the point in C#.
Can you point me to an alternative article that might explain event subscription in another way that might sink into my reluctant brain? And also something that may help me get hold of a Form reference.
Thanks for your patience!!!
Steve
Steve Howard - 29 Dec 2005 18:29 GMT Let me rephrase this a little more succinctly.
How do I get Form1 to subscribe to the Closed event of Form2?
Steve
Steve Howard - 29 Dec 2005 18:46 GMT > Let me rephrase this a little more succinctly. > > How do I get Form1 to subscribe to the Closed event of Form2? In the great tradition of answering one's own question .... I finally think I figured it out.
private void OpenMenu()
{
//new instance of Main Menu form
//I had this reference to the mainMenu all along but 'didn't get it'
menuForm = new mainMenu();
//So subscribing to the main menu Closed event is easy
menuForm.Closed += new EventHandler(menuForm_Closed);
//Show it
menuForm.Show();
}
//Here's my event handler
private void menuForm_Closed(object sender, EventArgs e)
{
//Kill the whole program when the main menu is closed
this.Dispose();
}
So now for the million dollar question - did I do this right, or is there a better way? It is certainly working as I want it to - someone once told me "all working code is good code, but good code can usually be made into better code."
Steve
Chris Tacke, eMVP - 29 Dec 2005 19:46 GMT Call this.Close, not this.Dispose in the event handler.
 Signature Chris Tacke Co-founder OpenNETCF.org Are you using the SDF? Let's do a case study. Email us at d c s @ o p e n n e t c f . c o m http://www.opennetcf.org/donate
>> Let me rephrase this a little more succinctly. >> [quoted text clipped - 41 lines] > > Steve Steve Howard - 29 Dec 2005 22:06 GMT > Call this.Close, not this.Dispose in the event handler. Great, thank you!
Steve
Simon Hart - 30 Dec 2005 10:16 GMT Also, inheriting from IDisposable then implementing a Dispose method will allow you to easily handle disposing of resources that might need cleaning up. Because IDisposable is an interface you can use multiple inheritance IE:
public partial class LogbookWizard : Form, IDisposable
{
public void Dispose()
{
}
}
You can then call your form using the "using" verb. IE:
using (LogbookWizard logbook = new LogbookWizard)
{
logbook.ShowDialog();
}
When control is returned the implementation of Dispose will get called automatically.
Cheers
Simon.
>> Call this.Close, not this.Dispose in the event handler. > > Great, thank you! > > Steve Steve Howard - 30 Dec 2005 15:31 GMT > Also, inheriting from IDisposable then implementing a Dispose method will > allow you to easily handle disposing of resources that might need cleaning > up. Because IDisposable is an interface you can use multiple inheritance > IE: ...
> When control is returned the implementation of Dispose will get called > automatically. I am afraid this didn't make any sense to me at all :-( I guess I need to work with C# for a bit longer before this sort of thing makes sense ...
I do appreciate the input, though. Don't think think me ungrateful !!!
Steve
Simon Hart - 30 Dec 2005 19:23 GMT Try looking up "Using" and "IDisposable" in MSDN help.
Using the IDisposable interface extends the overridden Form class Dispose method which gets called explicitly or by the automatic garbage collector when it feels like it (memory running low). Even still, the gc will only collect managed resources, that is managed reference types that might have been declared and no longer have valid refernces anywhere. Using IDisposable allows you to clean up your unmanaged and managed data and database collections, connections etc.
I use the IDisposable extensively for business logic classes which make use of ADO.NET etc.
You might want to read up on Agile development methodologies such as eXtreme or XP as this goes into great real life detail regarding OO programming model and best practices using C#.
One book I recommend is: eXtreme .NET by Dr. Neil Roodyn. isbn 0-321-30363-6.
Cheers Simon.
>> Also, inheriting from IDisposable then implementing a Dispose method will >> allow you to easily handle disposing of resources that might need [quoted text clipped - 12 lines] > > Steve Steve Howard - 30 Dec 2005 19:49 GMT Simon,
thanks for the extra info. I'll look into this further ...
Can you tell me, meantime, if the technique you describe would help me with my current problem? I have a method that launches a form with a single PictureBox, then erases it after 3 seconds. The pictureBox form is launched when the user clicks a button. The user can do this multiple times, ans see the same or a different image, depending on choice made.
When multiple choices are made, the RAM used seems to never be released. I tried using Xlose, Dispose and setting the form reference to Null ... still memory used creeps up with every button click.
Incidentally I think you are just witnessing my frustration in not succeeding to 'just learn' C#. The vast majority of development work I have done over the last decade has been procedural, rather than OOP, and it seems I am not finding OOP as easy to pick up as certain of my colleagues have assured me I should ;-)
Thanks again.
Steve
Chris Tacke, eMVP - 30 Dec 2005 19:58 GMT Unless you're actually getting an out of memory exception don't worry about it. The GC doesn't reclaim memory immediately after release, but only when it needs to.
As for OOP, it's kinda like COM. It's a mystery for a while, then one day a light will come on in your head and you'll say "oooooohhhhh, now I get it!" You'll smack your forehead wondering why you thought it was so difficult, and move on. How long it takes to reach that day depends on the developer, but it's usually after 3-12 months of working with it.
 Signature Chris Tacke Co-founder OpenNETCF.org Are you using the SDF? Let's do a case study. Email us at d c s @ o p e n n e t c f . c o m http://www.opennetcf.org/donate
> Simon, > [quoted text clipped - 19 lines] > > Steve Steve Howard - 30 Dec 2005 20:32 GMT Thanks Chris.
> Unless you're actually getting an out of memory exception don't worry > about it. The GC doesn't reclaim memory immediately after release, but > only when it needs to. OK - I was aware of that, but I guess I thought I could take more control. So what should I use ... close, dispose? And is setting the reference to Null just a waste of typing?
> As for OOP, it's kinda like COM. It's a mystery for a while, then one day > a light will come on in your head and you'll say "oooooohhhhh, now I get > it!" You'll smack your forehead wondering why you thought it was so > difficult, and move on. How long it takes to reach that day depends on > the developer, but it's usually after 3-12 months of working with it. I have a pretty solid forehead so expect something akin to a thunderclap. Especially if it takes me 12 months!!!!! :-{
Steve
Chris Tacke, eMVP - 30 Dec 2005 20:45 GMT For my understanding of your goal, call Close. Nothing else.
 Signature Chris Tacke Co-founder OpenNETCF.org Are you using the SDF? Let's do a case study. Email us at d c s @ o p e n n e t c f . c o m http://www.opennetcf.org/donate
> Thanks Chris. > [quoted text clipped - 16 lines] > > Steve Chris Tacke, eMVP - 30 Dec 2005 20:47 GMT Prior experience developing usually puts you more toward the 3-month timeframe (though sometimes it's an inhibitor). Start trying to thing of everything as a class to wrap your brain around it. How would my beer be a class? My lunch. My commute. Put methods to each. Then start thinking about events. It'll come to you.
 Signature Chris Tacke Co-founder OpenNETCF.org Are you using the SDF? Let's do a case study. Email us at d c s @ o p e n n e t c f . c o m http://www.opennetcf.org/donate
> Thanks Chris. > [quoted text clipped - 16 lines] > > Steve Steve Howard - 30 Dec 2005 21:04 GMT > Prior experience developing usually puts you more toward the 3-month > timeframe (though sometimes it's an inhibitor). Start trying to thing of > everything as a class to wrap your brain around it. How would my beer be > a class? My lunch. My commute. Put methods to each. Then start > thinking about events. It'll come to you. The funny thing is I have no problem with making everything objects. The issues I am having are how OOP is implemented in C#. For instance, I wanted to pass a variable to a form on launch. My instinct was to add a property before showing the form, as this is what I have used in my brief forays into JavaScript and ActionScript
form Thing - new form(myForm); Thing.Var = myValue; Thing.Show();
Leaving aside any syntactical errors I might have made, we both know this doesn't work. Instead I have to add the property to the form in the form's cs file and set up code to accept the value I want to send as a parameter. It's a lot more complicated than I envisaged to do something I perceive as really basic.
Like you say, I am sure it will come to me, but meantime I cry like a baby whenever I have to spend 3 hours looking for something that should take about 7 seconds to implement.
Meantime, I rely on the patience of people like you, Chris, to help me out. It's a refreshing change in a way. In my more normal work, I am the expert answering questions answered by others.
Steve
 Signature Team Macromedia Volunteer - Authorware My blog - http://stevehoward.blogspot.com/ Blog RSS - http://stevehoward.blogspot.com/atom.xml Authorware tips - http://www.tomorrows-key.com
http://www.eurotaac.com
Simon Hart - 30 Dec 2005 22:17 GMT Steve,
>> Prior experience developing usually puts you more toward the 3-month >> timeframe (though sometimes it's an inhibitor). Start trying to thing of [quoted text clipped - 17 lines] > It's a lot more complicated than I envisaged to do something I perceive as > really basic. You can do this in C# but the recommended and easiest way is to use the Forms constructor.
You can also use access modifiers to enable you to change fields from outside the form. Setting a field to public for example will allow anyone/thing to access it without having to write a property (not recommended though).
> Like you say, I am sure it will come to me, but meantime I cry like a baby > whenever I have to spend 3 hours looking for something that should take > about 7 seconds to implement. C# really is easy once you get a grip on it which shouldn't take much time if you have a wealth of development experience. In fact I find C# the best language and .NET the best development technology platform I have ever used. I have a COBOL background too!
> Meantime, I rely on the patience of people like you, Chris, to help me > out. It's a refreshing change in a way. In my more normal work, I am the > expert answering questions answered by others. > > Steve Steve Howard - 31 Dec 2005 02:10 GMT >> Leaving aside any syntactical errors I might have made, we both know this >> doesn't work. Instead I have to add the property to the form in the [quoted text clipped - 4 lines] > You can do this in C# but the recommended and easiest way is to use the > Forms constructor. I **think** that's what I did ... still having a hard time using the correct terminology. Right now I am more interested in making it work than learning a new vocabulary ;-)
> C# really is easy once you get a grip on it which shouldn't take much time > if you have a wealth of development experience. In fact > I find C# the best language and .NET the best development technology > platform I have ever used. I have a COBOL background too! I first studied BASIC and COBOL about 20 years ago ... or so. But never used them professionally. I've been using Macromedia's Authorware for about 8 years, and the scripting language in it is roughly based on non-OOP PASCAL. This is a big leap. But fun too :-)
Steve
Simon Hart - 31 Dec 2005 09:21 GMT >> You can do this in C# but the recommended and easiest way is to use the >> Forms constructor. > > I **think** that's what I did ... still having a hard time using the > correct terminology. Right now I am more interested in making it work than > learning a new vocabulary ;-) Show us your code.
>> C# really is easy once you get a grip on it which shouldn't take much >> time if you have a wealth of development experience. In fact [quoted text clipped - 5 lines] > about 8 years, and the scripting language in it is roughly based on > non-OOP PASCAL. This is a big leap. But fun too :-) At my company we still have legacy Micro Focus COBOL code in our product today. We do use OO COBOL though which makes a big difference. I also learn't Pascal when studying many years ago, it's kind of like Delphi.
Cheers Simon.
Steve Howard - 31 Dec 2005 14:50 GMT >>> You can do this in C# but the recommended and easiest way is to use the >>> Forms constructor. [quoted text clipped - 4 lines] > > Show us your code. This is what I have in the form that is launched
/////////////// public SectSplash(int userChoiceFromParent)
{
InitializeComponent();
UserChoice = userChoiceFromParent;
}
public int UserChoice
{
set
{
pictureBox1.Image = imageList1.Images[value];
}
}
//////////////////
And in the launching form I have this
/////////////
private void LaunchSplash(int ChoiceNum)
{
newForm = new SectSplash(ChoiceNum);
//Show it
newForm.Show();
////////////////////
So the launched forn accepts a parameter (ChoiceFromParent) from the launching code. In the launching form the parameter ChoiceNum is sent to the SectSplash and captured as ChoiceFromParent. This value is then used to select an image from an ImageList to display in the PictureBox.
For consistency I should probably make the parameer names match, but since this is my first foray, I sometimes forego consistency for the sake of lots of documentation ;-)
> At my company we still have legacy Micro Focus COBOL code in our product > today. We do use OO COBOL > though which makes a big difference. > I also learn't Pascal when studying many years ago, it's kind of like > Delphi. I was let to believe that Delphi is Object Pascal ...
Steve
Simon Hart - 31 Dec 2005 17:24 GMT Steve,
I can't see anything wrong with your code. Is it not setting the correct image in the imagelist or are you getting a compile error/runtime error?
One thing (not connected to your problem) always used private access modifier on properties,data etc unless they are required outside of that object/class.
Cheers Simon.
>>>> You can do this in C# but the recommended and easiest way is to use the >>>> Forms constructor. [quoted text clipped - 68 lines] > > Steve Steve Howard - 31 Dec 2005 17:37 GMT Simon,
> I can't see anything wrong with your code. Is it not setting the correct > image in the imagelist or are you getting a compile error/runtime error? Oh no, it works exactly as I want now. I think we sort of moved on to "did I do it right?" :-)
> One thing (not connected to your problem) always used private access > modifier on properties,data etc unless they are required outside of that > object/class. You mean these two declarations?
-- public SectSplash(int userChoiceFromParent)
public int UserChoice --
OK I can fix that :-)
Thanks again!
Steve
Simon Hart - 31 Dec 2005 19:13 GMT Steve,
Just the property: public int UserChoice and generally and data that property uses.
So make it : private int UserChoice, that is if you don't need to set it from outside of that class.
Cheers Simon.
> Simon, > [quoted text clipped - 21 lines] > > Steve Steve Howard - 31 Dec 2005 20:07 GMT > Just the property: public int UserChoice and generally and data that > property uses. > > So make it : private int UserChoice, that is if you don't need to set it > from outside of that class. OK thanks - that makes sense.
Steve
Chris Tacke, eMVP - 29 Dec 2005 19:45 GMT Read this - it's the clearest description of events and delegates I've seen:
http://www.sellsbrothers.com/writing/default.aspx?content=delegates.htm
 Signature Chris Tacke Co-founder OpenNETCF.org Are you using the SDF? Let's do a case study. Email us at d c s @ o p e n n e t c f . c o m http://www.opennetcf.org/donate
> [Frustrated beginner alert!!] > [quoted text clipped - 23 lines] > > Steve
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|