Understanding C# Event Handler: why no event? - c#

Trying to get an event handler going, but more than that, understand the syntax behind these things. The following code compiles, I can see my DataGrid "SemesterView" inside Form1 but no event is triggered when the control SemesterView is entered, when I click on a cell, nuthin. What I am doing wrong? I've played around with other events in case I'm misunderstanding "Enter" but still nothing.
Within the form1 code
SemesterView semesterView;
semesterView = new SemesterView();
this.Controls.Add(semesterView);
semesterView.Enter += new SemesterView.EventHandler(semesterView.MyEvent1);
and in the SemesterView class
class SemesterView : DataGridView
{
public delegate void EventHandler(string p);
public event EventHandler Enter;
public SemesterView()
{// code to create columns rows etc}
public void MyEvent1(string p)
{ MessageBox.Show("event 1 works");}
}

You want to create a method that handles the event in SemesterView and tie the event to the handler:
class SemesterView : DataGridView
{
public void MyEvent(object sender, EventArgs args)
{
}
}
Then in Form1
SemesterView semesterView;
semesterView = new SemesterView();
this.Controls.Add(semesterView);
semesterView.Enter += semesterView.MyEvent;

Related

Stop Event popagation in Winforms

I was looking for a way to stop MouseDown event fired by an ObjectListView from propagation. Almost all suggestions in the net sad: use event.Handled = true;
However, Handled property is not there. I tried Cancel method but is not there too.
Basically, I have an ObjectListView defined as:
public class ObjectListView : Control
{
//...
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
//...
}
}
and I used this object in one of my forms to catch mouse click event in the ObjectListView. So I added an event handler in the form:
partial class Form1
{
private void InitializeComponent()
{
//...
this.ObjectListView.MouseDown +=
new System.Windows.Forms.MouseEventHandler(this.ObjectListView_MouseDown);
}
}
and defined within Form1 a delegate:
public partial class Form1
{
private void ObjectListView_MouseDown(object sender, MouseEventArgs e)
{
// Stop event propagation
}
}
So when I click on the ObjectListView in Form1, the Form1.ObjectListView_MouseDown method was called first and after that ObjectListView.OnMouseDown method.
I'm using .Net Framework 4.

How to get Usercontrol object 'X' from X's Button(i.e. Button inside the X) onclick event

Hello guys i am working on a Windows Form application in .Net C#.
Now i have a User control with a button inside it.
however i had to write the on-click handler in the main form rather than inside the user-control itself.
Now i want to know if there is anyway i can get the User-control object in the Button's on-click Handler. Since i had to make use of them few more times in the same form. I want to know which User-control's Button was click.
User Control
Button
Thank You :)
Here's an example of the UserControl raising a Custom Event that passes out the source UserControl that the Button was clicked on:
SomeUserControl:
public partial class SomeUserControl : UserControl
{
public event ButtonPressedDelegate ButtonPressed;
public delegate void ButtonPressedDelegate(SomeUserControl sender);
public SomeUserControl()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (ButtonPressed != null)
{
ButtonPressed(this); // pass the UserControl out as the parameter
}
}
}
Form1:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
someUserControl1.ButtonPressed += new SomeUserControl.ButtonPressedDelegate(SomeUserControl_ButtonPressed);
someUserControl2.ButtonPressed += new SomeUserControl.ButtonPressedDelegate(SomeUserControl_ButtonPressed);
someUserControl3.ButtonPressed += new SomeUserControl.ButtonPressedDelegate(SomeUserControl_ButtonPressed);
}
void SomeUserControl_ButtonPressed(SomeUserControl sender)
{
// do something with "sender":
sender.BackColor = Color.Red;
}
}
You can use event:
public delegate void ButtonClicked();
public ButtonClicked OnButtonClicked;
You can then subscribe the event anywhere, for instance, in your MainForm, you have a user control called demo;
demo.OnButtonClicked +=()
{
// put your actions here.
}
Just walk the .Parent() chain until you find a Control that is the same Type as your UserControl. In the example below, the UserControl is of Type SomeUserControl:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
someUserControl1.button1.Click += new EventHandler(button1_Click);
someUserControl2.button1.Click += new EventHandler(button1_Click);
someUserControl3.button1.Click += new EventHandler(button1_Click);
}
void button1_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
Control uc = btn.Parent;
while (uc != null && !(uc is SomeUserControl))
{
uc = uc.Parent;
}
uc.BackColor = Color.Red;
MessageBox.Show(uc.Name);
}
}

C#, How to create an event and listen for it in another class?

I can't figure out how to do this, heres sample code. Of what I wish to do.
public Class MainForm : Form
{
MyUserControl MyControl = new MyUserControl;
private void Button_Click(object sender, EventArgs e)
{
//Create MyEvent
}
}
public Class MyUserControl : UserControl
{
//listen for MyEvent from MainForm, and perform MyMethod
public void MyMethod()
{
//Do Stuff here
}
}
Step 1) Expose an event on MainForm... say..
public event Action simpleEvent
Step 2) Give MyUserControl a constructor that takes an instance of MainForm and bind an action to that event
public MyUserControl(MainForm form) {
form += () => Console.WriteLine("We're doing something!")
}
Step 3) raise the event in MainForm.Button_Click
if(simpleEvent != null) simpleEvent();
Note: You could register your own delegates and work with something other than lambda expressions. See http://msdn.microsoft.com/en-us/library/17sde2xt.aspx for a more thorough explanation
Your end result would look like...
public Class MainForm : Form
{
public event Action MyEvent;
MyUserControl MyControl = new MyUserControl(this);
private void Button_Click(object sender, EventArgs e)
{
if(simpleEvent != null) simpleEvent();
}
}
public Class MyUserControl : UserControl
{
//listen for MyEvent from MainForm, and perform MyMethod
public MyUserControl(MainForm form) {
simpleEvent += () => MyMethod();
}
public void MyMethod()
{
//Do Stuff here
}
}
This is how to delegate to an event of a private member, so the outside can listen to it.
public event EventHandlerType EventHandlerName
{
add
{
this._privateControl.EventHandlerName += value;
}
remove
{
this._privateControl.EventHandlerName -= value;
}
}
Another option would be to have an event in your form class:
public event EventHandler MyEvent;
And listen to the private member's event:
this._customControl.SomeEvent += this.SomeEventHandler;
With this:
private void SomeEventHandler(object sender, EventArgs e)
{
if (this.MyEvent != null)
{
this.MyEvent(this, e);
}
}
The usage from the outside in both cases will be the same:
var form = new Form1();
form1.MyEvent += (o, e) => { Console.WriteLine("Event called!"); };
The bottom line is the you must implement functionality inside your form to allow the outside subscribe/listen to inner events.
//listen for MyEvent from MainForm, and perform MyMethod
That's the wrong way around. Publishing an event in control is useful, the control cannot possibly guess how it is going to get used. It however most certainly should not know anything about an event that may or may not be available in the form that it gets dropped on. That has the nasty habit of blowing up when the form just doesn't (yet) have the event. The bad kind too, a crash at design time that puts up the White Screen of Darn and prevents you from fixing the problem.
A form doesn't have to guess, it knows exactly what controls it has. So where ever in the form you might want to raise the event, just call the control's MyMethod method directly. And if that's wrong for some reason, like removing the control but not the call, then you just get a compile error that's easy to fix.

How to add a control to a panel on a form from another user control

I have a form1.cs and in that form I have a panel1, in the load event of the form1.cs I am adding a control to the panel1. Now my issue is, I have a control called Numbers.cs, I need to add another control to that panel1 but from this control in a button event. How can I do this?
public partial class Number : UserControl
{
public Number()
{
InitializeComponent();
}
private void btnAcceptWelcome_Click(object sender, EventArgs e)
{
//HERE I NEED TO PASS A CONTROL TO THE PANEL1 IN FORM1.CS
//NOT SURE HOW TO DO THIS.
}
}
MORE INFO
So basically I have a folder called UserControls and in that folder I have
Numbers.cs
Letters.cs
Welcome.cs
All of them user controls, then i have a form
Form1.cs
Form1.cs instantiates Welcome and it is added to a Panel1 on the Form1.cs on form load. Then Welcome.cs has a button, when I click this button I need to swap to Numbers.cs. But I dont know how to do this from Welcome.cs
Another way would be to use a Custom Event raised by Numbers and handled by Form1 to pass the control and add it to your Panel's Control Collection.
This is an example of an Custom Event added to UserControl1
Form1
public partial class Form1 : Form
{
UserControl2 mySecondControl = new UserControl2();
public Form1()
{
InitializeComponent();
userControl11.AddControl+=new EventHandler(SwapControls);
}
private void SwapControls(object sender, EventArgs e)
{
panel1.Controls.Remove(userControl11);
userControl11.AddControl -= new EventHandler(SwapControls);
panel1.Controls.Add(mySecondControl);
}
}
UserControl
public partial class UserControl1 : UserControl
{
public event EventHandler AddControl;
public UserControl1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
this.AddControl(this, new EventArgs());
}
}
Note:
Untested code
Assuming Form1 has (or can get) a reference to Number
Add an event handler to Number:
public partial class Number : UserControl
{
// event handler Form1 will subscribe to
public EventHandler<EventArgs> OnWelcomeAccepted = (o, e) => { };
public Number()
{
InitializeComponent();
}
private void btnAcceptWelcome_Click(object sender, EventArgs e)
{
// raise the event
OnWelcomeAccepted(sender, e);
}
}
...Form1 will have a subscription after InitializeComponent(); note the additional subscription to ControlAdded:
public partial class Form1 : Form {
public Form1()
{
InitializeComponent();
this.ControlAdded += Control_Added;
// subscribe to the event and provide the implementation
Number.OnWelcomAccepted += (o, e) => { Controls.Add(GetControl( )); }
}
private void Control_Added(object sender, System.Windows.Forms.ControlEventArgs e)
{
// process size and placement and show
}
}
No other control should be adding anything directly to Form1. Let Form1 control it's children.
One way is to have a reference to panel1 within numbers since both of them are created within form1 you can pass one as an argument to the other's constructor.
It's not very clear from your description but you can just pass the control you want in the constructor or a property. Since in C# objects are always by reference you will be action on the same control in the Button event. You can always write your own event and have the panel register for it. A more complete code sample would be great.
I'm still a little unsure of what you're doing exactly but that's OK. I think the most flexible approach is to create your own custom event. Outside of any class create a delegate:
public delegate void WelcomeClick(object sender, EventArgs e);
Inside Welcome you need to create the event handler, it can be either static or part of the instance:
public event WelcomeClick OnClick;
Inside the Button Click event in welcome you can just call that event with the same parameters:
if (OnClick != null)
OnClick(sender, e);

C# Custom Event Handler

I am a person learning c#, and I have a program with a Parent form and a Child form. I want the child form to raise an event so that the Parent form can do something. I copied some code, but I am not smart enough to see what is wrong. I don't know how to correctly code the event in the child form. The error is DatasourceUpdated is not defined. Can anyone help me out with a suggested fix?
In the Child form I have
public partial class Form2 : Form
{
public EventHandler DataSourceUpdated;
...
private void button2_Click(object sender, EventArgs e) //Done button
{
if (this.DataSourceUpdated != null) //raise the event
{
this.DatasourceUpdated();
}
this.Close();
}
In the parent form I have this:
private void myAddRecord()
{
string myID = string.Empty;
string myMessage = "Insert";
Form2 myForm = new Form2(myID, myMessage);
Form2.DatasourceUpdated += ChildUpdated;
myForm.Show();
Right now, you're declaring an EventHandler, not an event. Change this to:
public partial class Form2 : Form
{
public event EventHandler DataSourceUpdated;
...
private void button2_Click(object sender, EventArgs e) //Done button
{
if (this.DataSourceUpdated != null) //raise the event
{
this.DataSourceUpdated(this, EventArgs.Empty);
}
this.Close();
}
Also, when you go to subscribe to your event, you need to subscribe to the event on the instance, not on the class:
Form2 myForm = new Form2(myID, myMessage);
myForm.DataSourceUpdated+= ChildUpdated;
myForm.Show();
This is because the event is declared at the instance level, not statically.
Form2.DatasourceUpdated += ...
you are trying to attach your handler to the class try this instead
myForm.DatasourceUpdated += ...
Your code looks right, as far as I can tell, as long as you have an actual handler; you have not included that in your code. ChildUpdated needs to be a method that with the signature void (object sender, EventArgs e), and you should also raise the event like that this.DataSourceUpdated(this, null);
The signature is being specified by the fact that you're declaring the event as being handled by System.EventHandler, which has that signature. You can create your own delegates as well, if you want it to receive some special parameters or no parameters at all.
Also, you have an inaccurate casing in your example, this.DatasourceUpdated -> this.DataSourceUpdated, but I'll assume that's just in your example...?
.NET events have both a "sender" object and an "EventArgs" object. These need to be included when your event is called.
for example:
private void button2_Click(object sender, EventArgs e) //Done button
{
if (this.DataSourceUpdated != null) //raise the event
{
this.DatasourceUpdated(this, EventArgs.Empty);
}
this.Close();
}
First of all there's a small typo: DatasourceUpdated vs DataSourceUpdated. See the capital S? Also, don't forget the args and to declare the DataSourceUpdated as an event:
public event EventHandler DataSourceUpdated;
...
this.DataSourceUpdated(this, EventArgs.Empty);
Another problem I notice is that your calling a static member when you should be calling an instance member:
Form2.DatasourceUpdated += ChildUpdated;
to
myForm.DatasourceUpdated += ChildUpdated;

Categories

Resources