On my MDIform click event I am opening my Form2 by passing my control and one event like this:
Form2 Obj = new Form2(ListBox1, ListBox1_ItemChanged);
And my From2 has opening class declared like this:
private readonly ListBox m_AssigndTree;
private EventHandler navChange;
public Form2(ListBox1 AssigndTree, EventHandler ListBox1_ItemChanged)
{
InitializeComponent();
m_AssigndTree = AssigndTree;
navChange = NavBarGroup3_ItemChanged;
}
Now have a click event on Form2 and I want to fire the event ListBox1_ItemChanged How I can do that, as to invoke the event of same form I use to do directly myEvent.Invoke += (parameters)
I have the following event on Form2:
private void button1_DoubleClick(object sender, EventArgs e)
{
// navChange.Invoke +=
}
You can't raise an event, declared in another type, directly.
ListBox1_ItemChanged in your sample is just an instance of EventHandler delegate, this is not and event.
To call an event use it like a function:
m_AssigndTree.ItemChanged();
You'll need to make up the arguments
Related
I have made a winform application in c#. Now I added a class named Main_Form_1.
In Main_Form, there are some click events that I copied in Main_Form_1.
// Main_Form.cs
public partial class Main_Form : Form
{
...
// code here
...
}
// Main_Form_1.cs
public partial class Main_Form : Form
{
private void SomeButton_Click(object sender, EventArgs e)
{
...
}
}
Now I want to assign this SomeButton_Click event, but I can not see the events in the property window. How can I assign this event to SomeButton?
I'm pretty sure you mean the event handler SomeButton_Click here. You can add it to the Click event of button "SomeButton" with: SomeButton.Click += SomeButton_Click;
I know that VS will open an eventhandler stub by doubleclicking on an event.
I found the underlying event declaration in InitializeComponent of the form on which the button is located.
this.buttonWorkOn.Click += new System.EventHandler(this.buttonWorkOn_Click);
Can I use this event declaration (of Visual Studio) and register another eventhandling method with it?
Upon instantiation of that other form its eventhandling method would need to register itself with the click event of the button on the main form.
I have no clue how to do that even though I have read quite a bit about delegates and events and in principle I do understand how it works.
Thank you
If you right click on an event handler in the code editor and browse the definition you will find the way that it is declared, which you can then use in your own code.
For example, the declaration for a Button's Click event is:
public event EventHandler Click;
You can add these yourself and use them from other places to respond to events in any class you create.
Here's a sample form with a single button (added via the designer) that when clicked will raise its own event:
public partial class Form1 : Form
{
public event EventHandler ButtonClicked;
private void RaiseButtonClicked()
{
if (ButtonClicked != null)
ButtonClicked(this, EventArgs.Empty);
}
public Form1()
{
InitializeComponent();
}
private void Button1_Click(object sender, EventArgs e)
{
RaiseButtonClicked();
}
}
In another class you can then add a handler to that:
public class Responder
{
public Responder(Form1 form)
{
form.ButtonClicked += OnButtonClicked;
}
private void OnButtonClicked(object sender, EventArgs args)
{
MessageBox.Show("Button was clicked");
}
}
Now every instance of the Responder class will tell you when the button is clicked on the form.
By "Double clicking on an event", visual studio will generate an event handler for you. What you don't see is that visual studio also subscribes the generated event handler to the event, by adding a line of code in your designer file.
If goes something like this:
Double click 'clicked' event
Visual studio opens up your code file, and you have a new button1_clicked method, which is your event handler.
Your designer is updated with a line like button1.Clicked += button1_clicked
If you want to do manual event subscriptions, you can do so from your code file, by adding something like <formelement>.<event> += <eventhandler>. If you cant see available events in your intellisense, you can always check the online documentation. MSDN
(You should never change your designer file, as this is a generated file)
If you like to get multiple methods been executed when an event occurs you can simply add all of them in your code (or you can even add the same method multiple times):
private void DoSomething(object source, EventArgs eventArgs)
{
Console.WriteLine("Something happened.");
}
private void DoSomethingElse(object source, EventArgs eventArgs)
{
Console.WriteLine("Something else happened.");
}
private void AttachToEvent()
{
button1.Clicked += DoSomething;
button1.Clicked += DoSomethingElse;
button1.Clicked += DoSomething;
}
This would print out:
Something happened.
Something else happened.
Something happened.
OK – it was not my application, I just tried to improve on it.
Anyway, the question was who owns whom and who is visible where.
On the Mainform are controls for user input.
On MainForm a variable of type "class preview" is declared:
Preview pv
For the Preview class I added an event declaration named WorkOn:
public class Preview
{
#region "Variables"
#region "PublicEvent"
public event EventHandler WorkOn;
}
Then in the MainForm, the variable pv – declared as a class field - is instantiated within a method.
pv = new Preview()
after which the user input in the controls of the main form is checked and when ok saved in the variables of the preview class.
Then, the PreviewForm is instantiated within the preview class, with the instance of the owning class (preview --> as instance pv) passed as a variable to the instantiation of the PreviewForm.
I had to create this overloaded constructor because from the PreviewForm an eventhandler must be registered with the preview class to make this work – as I realized.
formPreview formPreview = new formPreview(this);
// this --> is the class preview, the instance pv
// Instantiation of FormPreview
public formPreview(Preview preview)
{
InitializeComponent();
this.preview = preview;
// now for the event in the preview class an eventhandling method
// of the preview form is registered:
preview.WorkOn += formPreview_Close;
}
This is the registered method of FormPreview:
private void formPreview_Close(object sender, EventArgs e)
{
this.Close();
}
I was reminded again that events can only be raised from the class that publishes the event. So I had to create a public event raising method within the class preview – here named OnWorkOn:
public void OnWorkOn()
{
if (WorkOn != null)
WorkOn(this, EventArgs.Empty);
}
And finally I could trigger the event from the MainForm within the button to whose underlying event I planned to register the eventhandling method of the PreviewForm in the first place.
Only now I had to use the class variable pv of the MainForm as it is the medium between the MainForm and the PreviewForm:
public void buttonWorkOn_Click(object sender, EventArgs e)
{
pv.OnWorkOn();
// raising the event, informing whoever is registered to it
//...
}
So the design of the application did not allow for registering any eventhandling method of the preview form directly on the MainForm. That was the problem and I didn't quite see through the whole design yet.
Well – this is the outcome of a german C# tutorial – the only german one I know of.
You'll find it here:
[https://www.youtube.com/watch?v=-zCiwcgxMHw&list=PLvvL1HRuCBItyw45XnCqEXzuegKQd3MfL][1]
The code is not available for download anymore, but I could provide it as I am through.
I have a VSTO addin for outlook 2013. I'm trying to register an event with an event handler for a Form closing event.
Here is my code from class Form1:
public delegate void MyEventHandler();
private event MyEventHandler Closing;
private void OtherInitialize()
{
this.Closing += new MyEventHandler(this.Form1_Closing);
}
Also from class Form1:
public Form1()
{
InitializeComponent();
OtherInitialize();
}
private void Form1_Closing(object sender, CancelEventArgs e)
{
// Not sure what to put here to make the application exit completely
// Looking for something similar to Pytthon's sys.exit() or
// Applicaton.Exit() in Forms Applicatons, I tried
// Applicaton.Exit() it did not work
}
When I run this I get the error and warning:
The warning:
Form1.Closing hides inherited member System.Windows.Forms.Form.Closing. Use the new keyword if hiding was intended
The error:
No overload for Form1_Closing matches delegate System.EventHandler
What do these errors/warnings mean? How can I properly register the Form1_Closing event handler for when the form is closed with either the X button or form.Close() Right now I'm able to call form.Close() but it doesn't seem to trigger the Form1_Closing event.
There is no need to declare the Closing event because the parent class provides the event out of the box. Moreover, you can simply set the event handler without declaring the delegate class (latest .net versions):
public Form1()
{
InitializeComponent();
OtherInitialize();
}
private void OtherInitialize()
{
Closing += Form1_Closing;
}
private void Form1_Closing(object sender, CancelEventArgs e)
{
// Not sure what to put here to make the application exit completely
// Looking for something similar to Pytthon's sys.exit() or
// Applicaton.Exit() in Forms Applicatons, I tried
// Applicaton.Exit() it did not work
}
I have a class (class1)
in this class i have a function and anther class:
class2 _class2 = new class2();
protected void Button_Click(object sender, EventArgs e)
{
//do something
}
Now I have another class (class2)
that have a button in it
I want to send the button the function (Button_Click) so i can insert it to
the button event click
(button.click +=)
the class2 build multiple buttons in a loop for class1,
i want that when some one click one of the buttons it will go to the event function (Button_Click) in
class 1
I hope I was clear
Thanks for your help
Change protected void Button_Click to public void Button_Click.
Then from somewhere else, go:
Button b; // defined in class2, for example
class1 _class1 = new class1();
b.Click += new EventHandler(_class1.Button_Click);
Are you trying to "bubble" the event from for example one user control to a calling user control? If so, you need to to these things:
In the control where the button is clicked (a):
- Add the event handler to the button.Click
In the caller control (b)
- Subscribe to the event creating a function which is referenced in the markup: usercontrol(a) theeventhandlerina="the function in b"
if class2 is within class one you could have an add function, something similare to
_class2 = new Class2();
_class2.AddButton("button1",ButtonClick);
_class2.AddButton("button2",ButtonClick);
_class2.AddButton("button3",ButtonClick);
//in class2
public void AddButton(string buttonName, EventHandler handler)
{
var newButton = new Button(buttonName);
newButton.click+= handler;
}
this is of course a contrived example but it should get the point across
I have a control which extends UserControl. This control contains two ComboBox controls. I've created an event handler which fires when either of the combos changes:
public event EventHandler ComboChanged
{
add { cmbA.SelectedIndexChanged += value; cmbB.SelectedIndexChanged += value; }
remove {...}
}
When I add an event handler to this event, is there any way for the sender to be reported as the custom control (i.e. the ComboBox's parent control) rather than the ComboBox itself? Or am I trying to do something I shouldn't be doing here?
You should have something like this :
public event EventHandler MyControlChanged
and then in your userControl two functions for each of the ComboBox
protected void oncmbA_SelectedIndexChanged(object sender, EventArgs e)
{
if (MyControlChanged!=null)
MyControlChanged(this, e);//or some new Eventagrs that you wish to communicate
}
protected void oncmbB_SelectedIndexChanged(object sender, EventArgs e)
{
if (MyControlChanged!=null)
MyControlChanged(this, e);//or some new Eventagrs that you wish to communicate
}
this would then refer to the UserControl and not to the combobox that fired your UserControl's event.
Yoann's answer is the way to go. Here's a similar pattern, but with some minor differences.
// Default listener makes null-check unnecessary when raising event.
// Note that no custom implementations are provided for add, remove.
public event EventHandler ComboChanged = delegate { };
...
foreach(var comboxBox in new[] {cmbA, cmbA})
{
// Attach listener to combo-box's event that raises our own event.
// Lambda-expression is ok since we don't intend to ever unsubscribe.
comboBox.SelectedIndexChanged += (sender, args) => ComboChanged(this, args);
}