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

using a delegate in a user control to pass click events to a parent form

P: n/a
Back in July, Jeffery Tan posted this:

http://groups.google.com/groups?hl=e...ngxa06.phx.gbl

In response as to how to get click events from a user control to
invoke a method in the parent form.

This code doesn't seem to work for me, I've tried it a number of times
with very simple test cases (A user control with a single button and a
parent form with a single text box) and it always raises the unhandled
exception "Object reference not set to instance of object" at the line
"pointer.DynamicInvoke(null);" in usercontrol.cs

Does anyone have any solutions to this that definitely work, or can
tell me what's wrong with the posting above?

Maybe this is a very basic thing I'm just not getting. Thanks in
advance for your help.

___
/<>/>/>
SkiTag Inc.
Nov 15 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a
The UserControl was not initialized in Form1. You needed to create a new
instance of the control by calling the constructor that takes the delegate
to be invoked.

userControl11 = new UserControl11(pointer);

This is the opposite of what I'd expect that you to be looking for.
Convention would dictate that the event be defined in the control and the
form would then subscribe to that event and provide a handler for it. Touch
back if you want a code sample of that.
Here's the new code for Form1:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace d
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Label label1;
private test.UserControl1 userControl11;
private System.ComponentModel.Container components = null;
public delegate void delegatecall();
private event delegatecall pointer;
public void cmdOkay_Click()
{
label1.Text ="parent method called";
}
public Form1()
{
pointer+=new delegatecall(this.cmdOkay_Click );
InitializeComponent();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
} base.Dispose( disposing );
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.userControl11 = new test.UserControl1(pointer);
this.SuspendLayout();
//
// label1
//
this.label1.Location = new System.Drawing.Point(96, 40);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(96, 64);
this.label1.TabIndex = 0;
this.label1.Text = "label1";
//
// userControl11
//
this.userControl11.BackColor = System.Drawing.SystemColors.ActiveCaption;
this.userControl11.Location = new System.Drawing.Point(48, 120);
this.userControl11.Name = "userControl11";
this.userControl11.Size = new System.Drawing.Size(150, 72);
this.userControl11.TabIndex = 1;
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(296, 238);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.userControl11,
this.label1});
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
}
}

HTH,
Eric Cadwell
http://www.origincontrols.com
Nov 15 '05 #2

P: n/a
Thanks Eric, that was precisely it. It works now (!!!)
The sample mentioned below of the conventional solution would be
appreciated, as I will be using this over and over in my app. It
seemed unusual to me too.
Thanks again..
___
/<>/>/>

"Eric Cadwell" wrote:
This is the opposite of what I'd expect that you to be looking for.
Convention would dictate that the event be defined in the control and the
form would then subscribe to that event and provide a handler for it. Touch
back if you want a code sample of that.

Nov 15 '05 #3

P: n/a
I created two samples. In both samples, the UserControl code is complete,
but the Form code only shows the form's constructor and the event handler.
The first sample simply connects an eventhandler to the inherent Click event
of the UserControl. The second sample creates a custom event that allows you
to pass data back to the form.

1. Since UserControl exposes a public Click event you can just add a handler
for it. To just catch the click event of the UserControl requires no custom
code in the UserControl itself and a lot less code in the form to respond to
it.

Form1.cs (only the significant parts of the code):

public Form1()
{
InitializeComponent();
this.userControl11.Click += new
System.EventHandler(this.userControl11_Click);
}
private void userControl11_Click(object sender, System.EventArgs e)
{
label1.Text = "event raised to parent.";
}
UserControl1.cs (all of the code)

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
namespace test
{
public class UserControl1 : System.Windows.Forms.UserControl
{
private System.ComponentModel.Container components = null;

public UserControl1()
{
InitializeComponent();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
} base.Dispose( disposing );
}
#region Component Designer generated code
private void InitializeComponent()
{
this.SuspendLayout();
//
// UserControl1
//
this.BackColor = System.Drawing.SystemColors.ActiveCaption;
this.Name = "UserControl1";
this.Size = new System.Drawing.Size(152, 150);
this.ResumeLayout(false);
}
#endregion
}
}

2. In this sample you see the creation of a custom event that returns a
custom EventArgs class. This is more work, but you'll need to do this for
more complex events when you want to pass data to the listener of the event.
By clicking the button inside the UserControl it raises the custom event to
the form (if registered).

Form1.cs (only the significant parts of the code):

public Form1()
{
InitializeComponent();
userControl11.CustomClick += new
test.CustomClickHandler(userControl11_CustomClick) ;
}
private void userControl11_CustomClick(object sender,
test.CustomClickEventArgs e)
{
label1.Text = e.CursorLocation.ToString();
}

UserControl1.cs (all of the code)

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
namespace test
{

public delegate void CustomClickHandler(object sender, CustomClickEventArgs
e);

public class CustomClickEventArgs : EventArgs
{
Point cursorLocation;

public CustomClickEventArgs(Point CursorLocation)
{
cursorLocation = CursorLocation;
}
public Point CursorLocation
{
get { return cursorLocation; }
}
}
public class UserControl1 : System.Windows.Forms.UserControl
{
private System.Windows.Forms.Button button1;
private System.ComponentModel.Container components = null;
public event CustomClickHandler CustomClick;

public UserControl1()
{
InitializeComponent();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
} base.Dispose( disposing );
}
#region Component Designer generated code
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// button1
//
this.button1.BackColor = System.Drawing.SystemColors.Control;
this.button1.Location = new System.Drawing.Point(8, 8);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(136, 23);
this.button1.TabIndex = 0;
this.button1.Text = "fire custom event";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// UserControl1
//
this.BackColor = System.Drawing.SystemColors.ActiveCaption;
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.button1});
this.Name = "UserControl1";
this.Size = new System.Drawing.Size(152, 150);
this.ResumeLayout(false);
}
#endregion
private void button1_Click(object sender, System.EventArgs e)
{
if (CustomClick != null)
CustomClick(this, new CustomClickEventArgs(Cursor.Position));
}
}
}

HTH,
Eric Cadwell
http://www.origincontrols.com
Nov 15 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.