Event subscription and form reference - Suffering fundamental misunderstanding

S

Steve Howard

[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
 
S

Steve Howard

Let me rephrase this a little more succinctly.


How do I get Form1 to subscribe to the Closed event of Form2?


Steve
 
S

Steve Howard

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
 
S

Simon Hart

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.
 
S

Steve Howard

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
 
S

Simon Hart

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.
 
S

Steve Howard

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
 
C

Chris Tacke, eMVP

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.

--
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
 
S

Steve Howard

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
 
C

Chris Tacke, eMVP

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.

--
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
 
S

Steve Howard

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


--
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
 
S

Simon Hart

Steve,
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.

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!
 
S

Steve Howard

Leaving aside any syntactical errors I might have made, we both know this
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
 
S

Simon Hart

You can do this in C# but the recommended and easiest way is to use the
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.
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 :)

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.
 
S

Steve Howard

You can do this in C# but the recommended and easiest way is to use the
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
 
S

Simon Hart

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.

Steve Howard said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top