473,326 Members | 2,104 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,326 software developers and data experts.

Subscribe and unsubscribe to Windows.Forms.Controls events automatically

I created the following code:

private struct StackItem
{
public EventHandler theEvent, theHandler;
public StackItem(EventHandler theEvent, EventHandler theHandler)
{
this.theEvent = theEvent;
this.theHandler = theHandler;
}
}

protected void AddHandler(EventHandler theEvent, EventHandler theHandler)
{
theEvent += theHandler; // add handler to event
stack.Push(new StackItem(theEvent, theHandler)); // note the fact that we
did so
}

public virtual void Dispose()
{
while (stack.Count 0)
{
StackItem si = (StackItem)stack.Pop();
si.theEvent -= si.theHandler; // remove the handler from the event
}
}

So that my derived classes can register for various events of various
controls on my form without having to make certain to add both the subscribe
and unsubscribe lines of code. However, the following code:

AddHandler(form.listView.SizeChanged, new
System.EventHandler(this.listView_SizeChanged));

gives the following error:

"The event 'System.Windows.Forms.Control.SizeChanged' can only appear on the
left hand side of += or -="

I assume this is some attribute of the SizeChanged member of the various
stock controls. Is there any way around this?

Why do I need to unsubscribe? Because I'm using objects to implement various
states in my application. When the app changes states it needs to unhook the
current state object from all events so that the new state can take over.
Oct 11 '06 #1
4 6262
Hi

Did you used to program in VB.NET ?

This is usually the approach taken in Vb.net to add a handler to an event,
in C# you use:
form.listView.SizeChanged += new
System.EventHandler(this.listView_SizeChanged) ;

--
Ignacio Machin
machin AT laceupsolutions.com
"Douglas Peterson" <Te******@nospam.msn.comwrote in message
news:%2****************@TK2MSFTNGP05.phx.gbl...
>I created the following code:

private struct StackItem
{
public EventHandler theEvent, theHandler;
public StackItem(EventHandler theEvent, EventHandler theHandler)
{
this.theEvent = theEvent;
this.theHandler = theHandler;
}
}

protected void AddHandler(EventHandler theEvent, EventHandler theHandler)
{
theEvent += theHandler; // add handler to event
stack.Push(new StackItem(theEvent, theHandler)); // note the fact that we
did so
}

public virtual void Dispose()
{
while (stack.Count 0)
{
StackItem si = (StackItem)stack.Pop();
si.theEvent -= si.theHandler; // remove the handler from the event
}
}

So that my derived classes can register for various events of various
controls on my form without having to make certain to add both the
subscribe and unsubscribe lines of code. However, the following code:

AddHandler(form.listView.SizeChanged, new
System.EventHandler(this.listView_SizeChanged));

gives the following error:

"The event 'System.Windows.Forms.Control.SizeChanged' can only appear on
the left hand side of += or -="

I assume this is some attribute of the SizeChanged member of the various
stock controls. Is there any way around this?

Why do I need to unsubscribe? Because I'm using objects to implement
various states in my application. When the app changes states it needs to
unhook the current state object from all events so that the new state can
take over.


Oct 12 '06 #2
"Douglas Peterson" <Te******@nospam.msn.comschrieb im Newsbeitrag
news:%2****************@TK2MSFTNGP05.phx.gbl...
>I created the following code:

private struct StackItem
{
public EventHandler theEvent, theHandler;
public StackItem(EventHandler theEvent, EventHandler theHandler)
{
this.theEvent = theEvent;
this.theHandler = theHandler;
}
}

protected void AddHandler(EventHandler theEvent, EventHandler theHandler)
{
theEvent += theHandler; // add handler to event
stack.Push(new StackItem(theEvent, theHandler)); // note the fact that we
did so
}

public virtual void Dispose()
{
while (stack.Count 0)
{
StackItem si = (StackItem)stack.Pop();
si.theEvent -= si.theHandler; // remove the handler from the event
}
}

So that my derived classes can register for various events of various
controls on my form without having to make certain to add both the
subscribe and unsubscribe lines of code. However, the following code:

AddHandler(form.listView.SizeChanged, new
System.EventHandler(this.listView_SizeChanged));

gives the following error:

"The event 'System.Windows.Forms.Control.SizeChanged' can only appear on
the left hand side of += or -="

I assume this is some attribute of the SizeChanged member of the various
stock controls. Is there any way around this?
The cause is, that SizeChanged is an event and not a delegate field or
property.
Events can only be used on the left side of += or -= operators.
(An exception are field like events wich inside!! the class where they are
defined behave like fields of a delegate type.) Even if SizeChanged was a
field or property of a delegate type your code wouldn't work, because
delegates are imutable, and the operations would create only new delegate
instances wich will be stored in your stack item, but not in the Control.
>
Why do I need to unsubscribe? Because I'm using objects to implement
various states in my application. When the app changes states it needs to
unhook the current state object from all events so that the new state can
take over.

possible solutions:
1. for every Event make a static method, wich is subscribed once and calls
the appropriate handler on the actual stateobject.

2. make two methods wich do all the subscribing and unsubscribing of the
event.

3. store the old state object, and for every event make a method or
codeblock wich does the subscribing and the unsubscribing:
if (olsState != null)
control.Event -= oldState.Handler();
control.Event += newState.Handler();

4. in the StackItem store the MemberInfo of the event.
Oct 12 '06 #3

"Christof Nordiek" <cn@nospam.dewrote in message
news:es**************@TK2MSFTNGP03.phx.gbl...
possible solutions:
1. for every Event make a static method, wich is subscribed once and calls
the appropriate handler on the actual stateobject.
This was my original method. The form handled the events and called virtual
members on the state objects. I didn't like it because it wasn't very
encapsulated.
2. make two methods wich do all the subscribing and unsubscribing of the
event.
This is the way I'm doing it currently, the objects subscribe in their
constructors and unsubscribe in the virtual Dispose method. This is tedius
and prone to mistakes. If I don't find another solution, I'll stick to this.
3. store the old state object, and for every event make a method or
codeblock wich does the subscribing and the unsubscribing:
if (olsState != null)
control.Event -= oldState.Handler();
control.Event += newState.Handler();
The different state objects don't all subscribe to the same events, thus the
desire for encapsulation.
4. in the StackItem store the MemberInfo of the event.
This looks promising. I don't know C# well enough at this point to make it
work so I am going to research it and learn something new.
There is a #5 as well that has since occurred to me:

5. Have the state objects create and destroy the controls.

Each state makes use of 95% of all the controls. The controls simply behave
a bit differently depending on the current state. There are quite a lot of
controls. So I don't like this one either.

Thanks for all the suggestions,
Douglas
Oct 13 '06 #4
After researching MethodInfo, turns out I need EventInfo. It works great!
Here is the final code:

private class StackItem
{
public object control;
public System.Reflection.EventInfo eventInfo;
public System.EventHandler handler;
public StackItem(object control, string eventName, System.EventHandler
handler)
{
this.control = control;
this.eventInfo = control.GetType().GetEvent(eventName);
this.handler = handler;
this.eventInfo.AddEventHandler(this.control, this.handler);
}
public void Dispose()
{
this.eventInfo.RemoveEventHandler(this.control, this.handler);
}
}

private System.Collections.Stack stack = null;

public void Dispose()
{
while (stack.Count 0)
(this.stack.Pop() as StackItem).Dispose();
}

protected void AddHandler(object control, string eventName,
System.EventHandler handler)
{
if (this.stack == null)
this.stack = new Stack();
this.stack.Push(new StackItem(control, eventName, handler));
}
I simpy call AddHandler(form.listView, "SizeChanged", new
System.EventHandler(this.listView_SizeChanged)) in my derived State object's
constructor.

Thank you for your assistance,
Douglas
Oct 13 '06 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Tim Haughton | last post by:
I've just released an article on using Test Driven Development with C# and Windows Forms. GUI's are often difficult to test, so I thought it might be of interest. The article along with the...
2
by: Jon Davis | last post by:
The garbage handler in the .NET framework is handy. When objects fall out of scope, they are automatically destroyed, and the programmer doesn't have to worry about deallocating the memory space...
2
by: Joe | last post by:
Hi, I have a newsletter subscribe page. A user enters email address and clicks Subscribe button. That email address is added to database. Say this is a career newsletter. Is it possible to...
1
by: William Sullivan | last post by:
I've spent plenty of time building windows forms, but I'm working on a web project now. I've scanned a few ASP NET books, checked out some tutorials, but I am unable to figure out how to lay out...
6
by: | last post by:
Just a general question... When working with a form containing a treeview or similar control... if you need to show different form fields depending on what is selected in the treeview then what...
0
by: Kamilche | last post by:
''' event.py An event manager using publish/subscribe, and weakrefs. Any function can publish any event without registering it first, and any object can register interest in any event, even...
4
by: ljh | last post by:
I am trying to run some pretty simple code that monitors a folder for changes (copied the example at http://www.codeproject.com/dotnet/folderwatcher.asp). But, when I try and update a textbox...
5
by: Joe | last post by:
I have a usercontrol which has an event called NameChanged; The form that uses the control subscribes to NameChanged. The first time this form is invoked everything works fine. The second time I...
14
by: =?Utf-8?B?UHVjY2E=?= | last post by:
Hi, I'm using VS2005 and .net 2.0. I'm creating an application that has 3 forms. I want allow users to move forward and backward with the forms and retain the data users have entered. I thought...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

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.