By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,953 Members | 1,562 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,953 IT Pros & Developers. It's quick & easy.

Connecting an event handler in one class and disconnecting it in a different class.

P: n/a
In my code, class A instanciates classes B and C.

I would like class B to connect an event handler to a method in class A, and
for class C to disconnect that event handler.

I think I've done too much thinking, and now I'm even more confused as to
how to accomplish this as when I started.

Any help will be appreciated.
Nov 15 '05 #1
Share this Question
Share on Google+
10 Replies


P: n/a
Hi,

Thanks for posting. The following code is for your reference:

using System;

public delegate void ADelegate();

public class A
{
public static void Main(string[] args)
{
B b = new B();
ADelegate d = new ADelegate(AMethod);
b.AEvent += d;
C c = new C();
c.RemoveDelegateFromB(d, b);
}

public static void AMethod()
{
Console.WriteLine("A method");
}
}

public class B
{
public event ADelegate AEvent;
public void RaiseAEvent()
{
if (AEvent != null)
{
AEvent();
}
}
}

public class C
{
public void RemoveDelegateFromB(ADelegate d, B b)
{
b.AEvent -= d;
}
}

I hope this helps. If there is anything else I can help with, please feel
free to post here.

Regards,

Felix Wang
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

Nov 15 '05 #2

P: n/a
Assuming that ClassB and ClassC have a reference to ClassA then there should
be no Problem in doing this.

class ClassA
{
ClassB cl_B=null;
ClassC cl_C=null;
Panel pn_Panel=null
public ClassA()
{
pn_Panel = new Panel();
cl_B = new ClassB(this);
cl_C = new ClassC(this);
}
public void Dispose()
{
if (cl_C != null)
cl_C=null;
}
protected virtual void OnMouseDown(object
sender,System.Windows.Forms.MouseEventArgs e)
{
if (i_DragDrop == 0)
{
OnDragDrop(e.X,e.Y); // Do what must be done and check the results, set
i_DragDrop if something found
} // if (i_DragDrop == 0)
} // protected override void OnMouseDown(object
sender,System.Windows.Forms.MouseEventArgs e)
} // Class A

class ClassB
{
public ClassB(ClassA cl_A)
{
cl_A.pn_Panel.MouseDown += new
System.Windows.Forms.MouseEventHandler(cl_A.OnMous eDown);
}
} // ClassB
class ClassC
{
ClassA cl_A=null;
public ClassC(ClassA clA)
{
cl_A = clA;
}
public void Dispose()
{
if (cl_A != null)
cl_A.pn_Panel.MouseDown -= new
System.Windows.Forms.MouseEventHandler(cl_A.OnMous eDown);
}
} // ClassC

This should work.
This works in my Projects where a ClassA calls ClassB assuming that ClassB
will clean up what it has done in ClassA when closing.
Note : since ClassA is only needed in the Construction of ClassB here, it is
not saved to a Class Field as in ClassC.

Mark Johnson, Berlin Germany
mj*****@mj10777.de

"SunshineGirl" <bl**@blah.com> schrieb im Newsbeitrag
news:10*************@corp.supernews.com...
In my code, class A instanciates classes B and C.

I would like class B to connect an event handler to a method in class A, and for class C to disconnect that event handler.

I think I've done too much thinking, and now I'm even more confused as to
how to accomplish this as when I started.

Any help will be appreciated.

Nov 15 '05 #3

P: n/a
Not quite.

Class A must hold the code for the event.
Class B must connect an event handler (+=), not raise the event.
Class C must disconnect the event handler (-=).

This is an already running application to which I'm trying to add
functionality. Class B uses Windows instrumentation to receive a
notification when the user launches an application. Class C uses Windows
instrumentation to receive a notification when the user terminates an
application. Class A instanciates both classes B and C. Classes B and C
don't know about each other.

The application currently monitors when the user has launched or terminated
applications. I'm trying to add the following functionality.

Whenever class B receives notification that Internet Explorer has launched,
it needs to connect the BeforeNavigate2 event handler to a method in class A
(so class B must do the += thing: ie.BeforeNavigate2 += new
SHDocVw.DWebBrowserEvents2_BeforeNavigate2EventHan dler(this.ie_BeforeNavigat
e2). Whenever class C receives notification that Internet Explorer has been
terminated, it needs to disconnect the BeforeNavigate2 event handler (so
class C must do the -= thing: ie.BeforeNavigate2 -= new
SHDocVw.DWebBrowserEvents2_BeforeNavigate2EventHan dler(this.ie_BeforeNavigat
e2).

"Felix Wang" <v-*****@online.microsoft.com> wrote in message
news:sT*************@cpmsftngxa07.phx.gbl...
Hi,

Thanks for posting. The following code is for your reference:

using System;

public delegate void ADelegate();

public class A
{
public static void Main(string[] args)
{
B b = new B();
ADelegate d = new ADelegate(AMethod);
b.AEvent += d;
C c = new C();
c.RemoveDelegateFromB(d, b);
}

public static void AMethod()
{
Console.WriteLine("A method");
}
}

public class B
{
public event ADelegate AEvent;
public void RaiseAEvent()
{
if (AEvent != null)
{
AEvent();
}
}
}

public class C
{
public void RemoveDelegateFromB(ADelegate d, B b)
{
b.AEvent -= d;
}
}

I hope this helps. If there is anything else I can help with, please feel
free to post here.

Regards,

Felix Wang
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

Nov 15 '05 #4

P: n/a
Hello,

Thanks for your update.

I would like to ask a question. What is the object that exposes the event
"BeforeNavigate2" and how do you get a reference to it? If we can get the
reference (e.g. named "o") successfully, we can simply call
"o.BeforeNavigate2 += " in class B and "o.BeforeNavigate2 -= " in class C.

In addition, since the method for the event is defined in class A, we
cannot use "this" in class B and class C. If we define the method as
static, we can use "o.BeforeNavigate2 += new
SHDocVw.DWebBrowserEvents2_BeforeNavigate2EventHan dler(A.ie_BeforeNavigate2)
". If the method is non-static, we need to pass a reference to A into B or
simply create a new A object, so that the method can be accessed.

I hope this helps.

Regards,

Felix Wang
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

Nov 15 '05 #5

P: n/a
I should have thought of that.

Thanks for the response.
"Mark Johnson" <mj*****@mj10777.de> wrote in message
news:40**********************@newsread2.arcor-online.net...
Assuming that ClassB and ClassC have a reference to ClassA then there should be no Problem in doing this.

class ClassA
{
ClassB cl_B=null;
ClassC cl_C=null;
Panel pn_Panel=null
public ClassA()
{
pn_Panel = new Panel();
cl_B = new ClassB(this);
cl_C = new ClassC(this);
}
public void Dispose()
{
if (cl_C != null)
cl_C=null;
}
protected virtual void OnMouseDown(object
sender,System.Windows.Forms.MouseEventArgs e)
{
if (i_DragDrop == 0)
{
OnDragDrop(e.X,e.Y); // Do what must be done and check the results, set i_DragDrop if something found
} // if (i_DragDrop == 0)
} // protected override void OnMouseDown(object
sender,System.Windows.Forms.MouseEventArgs e)
} // Class A

class ClassB
{
public ClassB(ClassA cl_A)
{
cl_A.pn_Panel.MouseDown += new
System.Windows.Forms.MouseEventHandler(cl_A.OnMous eDown);
}
} // ClassB
class ClassC
{
ClassA cl_A=null;
public ClassC(ClassA clA)
{
cl_A = clA;
}
public void Dispose()
{
if (cl_A != null)
cl_A.pn_Panel.MouseDown -= new
System.Windows.Forms.MouseEventHandler(cl_A.OnMous eDown);
}
} // ClassC

This should work.
This works in my Projects where a ClassA calls ClassB assuming that ClassB will clean up what it has done in ClassA when closing.
Note : since ClassA is only needed in the Construction of ClassB here, it is not saved to a Class Field as in ClassC.

Mark Johnson, Berlin Germany
mj*****@mj10777.de

"SunshineGirl" <bl**@blah.com> schrieb im Newsbeitrag
news:10*************@corp.supernews.com...
In my code, class A instanciates classes B and C.

I would like class B to connect an event handler to a method in class A,

and
for class C to disconnect that event handler.

I think I've done too much thinking, and now I'm even more confused as to how to accomplish this as when I started.

Any help will be appreciated.


Nov 15 '05 #6

P: n/a
The object that exposes the BeforeNavigate2 event is the Internet Explorer
ShellWindows interface.

Here is that part of the code that connects the event handler. This is from
a Windows app and it works. Now it must be in class B):
private static SHDocVw.ShellWindows shellWindows = new
SHDocVw.ShellWindowsClass();

foreach(SHDocVw.InternetExplorer ie in shellWindows)
ie.BeforeNavigate2 += new
SHDocVw.DWebBrowserEvents2_BeforeNavigate2EventHan dler(this.ie_BeforeNavigat
e2);

This is the event handler (that must be in class A):
public void ie_BeforeNavigate2(object pDisp , ref object url, ref object
Flags, ref object TargetFrameName, ref object PostData, ref object
Headers, ref bool Cancel)
{
MessageBox.Show("BeforeNavigate2: " + url.ToString());
}

Thank you for your help.
"Felix Wang" <v-*****@online.microsoft.com> wrote in message
news:Qz**************@cpmsftngxa07.phx.gbl...
Hello,

Thanks for your update.

I would like to ask a question. What is the object that exposes the event
"BeforeNavigate2" and how do you get a reference to it? If we can get the
reference (e.g. named "o") successfully, we can simply call
"o.BeforeNavigate2 += " in class B and "o.BeforeNavigate2 -= " in class C.

In addition, since the method for the event is defined in class A, we
cannot use "this" in class B and class C. If we define the method as
static, we can use "o.BeforeNavigate2 += new
SHDocVw.DWebBrowserEvents2_BeforeNavigate2EventHan dler(A.ie_BeforeNavigate2) ". If the method is non-static, we need to pass a reference to A into B or
simply create a new A object, so that the method can be accessed.

I hope this helps.

Regards,

Felix Wang
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

Nov 15 '05 #7

P: n/a
Here's how far I got. But it doesn't work. Class B never enters the foreach loop.

ClassA:
public static SHDocVw.ShellWindows shellWindows = null;

public void ie_BeforeNavigate2(object disp, ref object url, ref object flags, ref object targetFrameName, ref object postData, ref object headers, ref bool cancel)
{
MessageBox.Show("BeforeNavigate2: " + url.ToString());
}

ClassB:
private ClassA classA = null;

in the constructor:
ClassA.shellWindows = new SHDocVw.ShellWindowsClass();
foreach(SHDocVw.InternetExplorer ie in ClassA.shellWindows)
ie.BeforeNavigate2 += new SHDocVw.DWebBrowserEvents2_BeforeNavigate2EventHan dler(classA.ie_BeforeNavigate2);

ClassC:
private ClassA classA = null;

in the constructor:
ClassA.shellWindows = new SHDocVw.ShellWindowsClass();
foreach(SHDocVw.InternetExplorer ie in ClassA.shellWindows)
ie.BeforeNavigate2 -= new SHDocVw.DWebBrowserEvents2_BeforeNavigate2EventHan dler(classA.ie_BeforeNavigate2);


"SunshineGirl" <bl**@blah.com> wrote in message news:10*************@corp.supernews.com...
The object that exposes the BeforeNavigate2 event is the Internet Explorer
ShellWindows interface.

Here is that part of the code that connects the event handler. This is from
a Windows app and it works. Now it must be in class B):
private static SHDocVw.ShellWindows shellWindows = new
SHDocVw.ShellWindowsClass();

foreach(SHDocVw.InternetExplorer ie in shellWindows)
ie.BeforeNavigate2 += new
SHDocVw.DWebBrowserEvents2_BeforeNavigate2EventHan dler(this.ie_BeforeNavigat
e2);

This is the event handler (that must be in class A):
public void ie_BeforeNavigate2(object pDisp , ref object url, ref object
Flags, ref object TargetFrameName, ref object PostData, ref object
Headers, ref bool Cancel)
{
MessageBox.Show("BeforeNavigate2: " + url.ToString());
}

Thank you for your help.


"Felix Wang" <v-*****@online.microsoft.com> wrote in message
news:Qz**************@cpmsftngxa07.phx.gbl...
Hello,

Thanks for your update.

I would like to ask a question. What is the object that exposes the event
"BeforeNavigate2" and how do you get a reference to it? If we can get the
reference (e.g. named "o") successfully, we can simply call
"o.BeforeNavigate2 += " in class B and "o.BeforeNavigate2 -= " in class C.

In addition, since the method for the event is defined in class A, we
cannot use "this" in class B and class C. If we define the method as
static, we can use "o.BeforeNavigate2 += new

SHDocVw.DWebBrowserEvents2_BeforeNavigate2EventHan dler(A.ie_BeforeNavigate2)
". If the method is non-static, we need to pass a reference to A into B or
simply create a new A object, so that the method can be accessed.

I hope this helps.

Regards,

Felix Wang
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.


Nov 15 '05 #8

P: n/a
Hello,

Thanks for your update. Let's try the following:

ClassA:
public static SHDocVw.ShellWindows shellWindows = new
SHDocVw.ShellWindowsClass();

public static void ie_BeforeNavigate2(object disp, ref object url, ref
object flags, ref object targetFrameName, ref object postData, ref object
headers, ref bool cancel)
{
MessageBox.Show("BeforeNavigate2: " + url.ToString());
}

ClassB:

in the constructor

foreach(SHDocVw.InternetExplorer ie in ClassA.shellWindows)
ie.BeforeNavigate2 += new
SHDocVw.DWebBrowserEvents2_BeforeNavigate2EventHan dler(ClassA.ie_BeforeNavig
ate2);

ClassC:

in the constructor

foreach(SHDocVw.InternetExplorer ie in ClassA.shellWindows)
ie.BeforeNavigate2 -= new
SHDocVw.DWebBrowserEvents2_BeforeNavigate2EventHan dler(ClassA.ie_BeforeNavig
ate2);

Since the "shellWindows" is a static member, we can access it from both
ClassB and ClassC. We only need to "new" it once in ClassA. I have not
tested the code with IE. But from C# language's perspective, it should
work. I hope this helps.

Regards,

Felix Wang
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

Nov 15 '05 #9

P: n/a
Thanks. That worked in a Windows application. However, I can't get it to
work inside a Windows service, which is what I want. I get the following
exception when I run the line "shellWindows = new
SHDocVw.ShellWindowsClass();":

COM object with CLSID {9BA05972-F6A8-11CF-A442-00A0C90A8F39} is either not
valid or not registered.

I know that this CLSID belongs to ShellWindows.

Any ideas?

Thanks again.
"Felix Wang" <v-*****@online.microsoft.com> wrote in message
news:Uw**************@cpmsftngxa08.phx.gbl...
Hello,

Thanks for your update. Let's try the following:

ClassA:
public static SHDocVw.ShellWindows shellWindows = new
SHDocVw.ShellWindowsClass();

public static void ie_BeforeNavigate2(object disp, ref object url, ref
object flags, ref object targetFrameName, ref object postData, ref object
headers, ref bool cancel)
{
MessageBox.Show("BeforeNavigate2: " + url.ToString());
}

ClassB:

in the constructor

foreach(SHDocVw.InternetExplorer ie in ClassA.shellWindows)
ie.BeforeNavigate2 += new
SHDocVw.DWebBrowserEvents2_BeforeNavigate2EventHan dler(ClassA.ie_BeforeNavig ate2);

ClassC:

in the constructor

foreach(SHDocVw.InternetExplorer ie in ClassA.shellWindows)
ie.BeforeNavigate2 -= new
SHDocVw.DWebBrowserEvents2_BeforeNavigate2EventHan dler(ClassA.ie_BeforeNavig ate2);

Since the "shellWindows" is a static member, we can access it from both
ClassB and ClassC. We only need to "new" it once in ClassA. I have not
tested the code with IE. But from C# language's perspective, it should
work. I hope this helps.

Regards,

Felix Wang
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

Nov 15 '05 #10

P: n/a
excelent.
regards.
"Felix Wang" <v-*****@online.microsoft.com> wrote in message
news:sT*************@cpmsftngxa07.phx.gbl...
Hi,

Thanks for posting. The following code is for your reference:

using System;

public delegate void ADelegate();

public class A
{
public static void Main(string[] args)
{
B b = new B();
ADelegate d = new ADelegate(AMethod);
b.AEvent += d;
C c = new C();
c.RemoveDelegateFromB(d, b);
}

public static void AMethod()
{
Console.WriteLine("A method");
}
}

public class B
{
public event ADelegate AEvent;
public void RaiseAEvent()
{
if (AEvent != null)
{
AEvent();
}
}
}

public class C
{
public void RemoveDelegateFromB(ADelegate d, B b)
{
b.AEvent -= d;
}
}

I hope this helps. If there is anything else I can help with, please feel
free to post here.

Regards,

Felix Wang
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

Nov 15 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.