Is there a way to subscribe to this event or something similar so I can perform some clean up codes before objects are finalized?
The event is static so using it in a DLL doesn't cause any problem.
Do beware however that the event is only fired if your class library is actually used from a Winforms application. You can only be sure of that if you expose functionality that is only usable from a Winforms app. Like a custom control or UserControl.
Alternatives are the AppDomain events, DomainUnload and ProcessExit. Or just expecting the main app to let you know about the shutdown. Which is usually the better choice, you don't necessarily know why the app is exiting. You wouldn't want to save settings on a hard crash for example. Note how the ApplicationSettingsBase class follows that pattern as well, you have to explicitly call its Save() method.
You subscribe to this event in the same manner you would with any event.
The example on the ApplicationExit MSDN page is clear:
Application.ApplicationExit += new EventHandler(this.OnApplicationExit);
private void OnApplicationExit(object sender, EventArgs e) {
// do your cleanups
}
Related
I take charge of a development of an older WPF modular application using Prism Library for WPF. In this case, entry point to the application for me is an overriden Initialize() method since I have no access to the Application.MainWindow's App class. This class along with some other helper classes is compiled to EXE file and DLL's.
Currently I'm facing to a problem that I have to catch the Window.Closing event which is not raised during closing the application. Normally this piece of code which is put into the constructor (in this specific case into Initialize() method) is working as expected
Application.Current.MainWindow.Closing += (s, e) =>
{
e.Cancel = true;
};
On the other hand, event Window.Closed is fired up without any issues.
In my opinion it's not possible to associate this event handler outside of Application.MainWindow's constructor, or do I something wrong? Please help me.
The issue was located. The OnClosing method which raises the Closing event is implemented in the shell and it looks like this
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
e.Cancel = true;
ViewModel.StartShutdownSequence();
}
The StartShutdownSequence() encapsulates some logic regarding handling individual modules and at the end it calls Application.Current.Shutdown() which definitely shutdown the application.
Is it possible in c# to dispatch own events to controls?
I mean, like you can do in java:
MouseEvent leftClick = new MouseEvent(image, MouseEvent.MOUSE_PRESSED,
0, 0, 100, 100, 1, false, MouseEvent.BUTTON1);
image.dispatchEvent(leftClick);
Events in C# work a little differently. Instead of dispatching an event to the object, you subscribe to an event the object has available and provide a delegate. See Events (C# vs. Java) for reference. However, if you want to run the code attached to an event, you can call the delegate directly, but I think most people would consider this bad form. It may be better to have a method which performs the action and call it from both the delegate and wherever you are wanting to simulate the click event from.
SomeControl.LeftMouseButtonDown += new LeftMouseButtonDown(SomeControl_LeftMouseButtonDown);
protected void SomeControl_LeftMouseButtonDown(object sender, EventArgs e) //Might be typed EventArgs instead of generic.
{
//Run some code or call some method.
}
Preferably, you would use the Click event instead of the LeftMouseButtonDown as the Click event is thrown on LeftMouseButtonDown and LeftMouseButtonUp when they occur consecutively.
Are you working with a control that does not have a LeftMouseButtonDown or Click event? If so, you will need to write your own control that inherits from that control and write your own event.
Also, it would help if you provided some details over which .NET technology you are using (WPF, WinForms, ASP.NET, Silverlight, etc) as each has a different control set. It may also be helpful to know which control you are using from that technology.
Hope this helps though!
I wrote the MouseController for NUnitForms. Its designed to work with Windows Forms and simulates the events by placing the events into the Windows event queue.
You can view the source at http://nunitforms.svn.sourceforge.net/viewvc/nunitforms/trunk/nunitforms/source/NUnitForms/MouseController.cs?revision=69&view=markup
How can I register to event and do some actions at runtime?
For example when the user click on a button I want to register to OnMyEvent and run MyFunc that let's say initialize some textBox with the OnMyEvent args.
I'm using winforms and .NET 4.
EDIT
Maybe I was unclear... I need the ability to register to existing event and add a new method that will run when the event will fire. All at runtime.
EDIT2
i'll try to give an example...
lets say that i have a class named "A" that have many events OnDataRecived OnDataSend etc...
when the application running the user can choose form a combobox event name to register (i got the events list via reflection because they not constracts, they are generated from xml file) and which data to update when the choosed event is fired.
so for the example the user choose to register to the OnDataReceived and he choose to update property named DataStream. some code...
in run time upon user choosing:
A.OnDataReceived += (s,e) => MyRunTimeMethod(s,e);
private void MyRunTimeMethod(object sender, EventArgs e)
{
DataStream = e.Data.Value
}
You are asking how to create a method dynamically at runtime - once you have a reference to that method in a delegate, the question of how to register it to an event is trivial.
MSDN describes how to do this with MSIL instructions. I doubt that's what you're looking for, but it is an option.
The C# FAQ blog has a much more interesting solution using expression trees. I suppose this is the one you were referring to by originally tagging your post with expression-tree.
But I would reconsider using dynamic methods at all. How exactly is the user going to specify what action to perform on the event of his choice? I suspect that the options are limited enough that you can get by with something simpler:
protected void btnRegister_Click(object sender, EventArgs e) {
switch (cmbEvents.SelectedText) {
case "OnLoad":
MyControl.OnLoad += (s, e) => SomeSelectedControl.Text = SomeInputControl.Text;
break;
//... other cases
}
}
If you're using windows forms, double clicking a button will bring you to a created on_click event. If you bring up the properties window for the button, theres an events tab. Viewing this will show you which events are available for a control.
I found the best way to understand this, was to look at the code created when adding the events.
Update:
As noted, I completely missed the point with my answer. The syntax for subscribing to an event at runtime is the same way as it's done on form Initialize. So I don't get any terminology wrong, here's the link to the msdn documentation;
http://msdn.microsoft.com/en-us/library/ms366768.aspx
What you want to achieve, does not require you to "Register to event at run time".
If button1 is the button of interest here, simply use.
button1.Click += buton1_ClickHandler;
button1_ClickHandler should be defined in the same class as your button1. and it should have the signature of the RoutedEventHandler. So, it should be
private void button1_ClickHandler(object sender, RoutedEventArgs e)
{
//method code here
}
Which one of these solutions looks nicer, and is more clearer?
In form's constructor:
textBox1.KeyDown += delegate(object o, KeyEventArgs e)
{
if (e.KeyCode== Keys.Enter)
{
button1.PerformClick();
}
};
Or:
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Return)
{
button1.PerformClick();
}
}
The choice of the implementation depends upon your requirements that we don't know exactly and that may change over time.
As long as your handler is not supposed to be added or removed dynamically or to contain any data that is known only at runtime I see no reason to wrap it into a delegate and add to your form. And you will need to implement your own destructor/Dispose() method to explicitly remove this handler to prevent memory leaks.
So, the second solution with static handler seems to me to be optimal here. You can then easily see what event handlers your textBox1 control actually implements directly in the properties of the control in Visual Studio and don't have to look for this handler implementation through your code if you need to modify it later.
The first one looks OK when you only have one event handler. However, what if you have 10 or 20? That would result in a pretty bloated constructor. It's definitely better to have the event handler, but even then it's best not to have a lot of business logic in an event handler.
Also, the uses of delegates in the constructor would prevent edit and continue from working.
It depends: if you could do it at design time I prefer the second.
If you use the first, remember to use textBox1.KeyDown -= before closing your form to avoid memory leaks.
According to me, the second is more clearly and look nicer, but the first help developers coding faster.
But, two solutions depend on your purpose.
It is a matter of style, but, personally, I avoid making anonymous delegates with more than one line of code. For instance, this works form me
btnSave.Click += (sender, e) => Save();
#Marco, Alexander:
How can one leak memory with those event handlers? I think it happens only if event source is static.
What is the proper way to fire an ASP.NET control event programatically?
I am looking to refactor a little code and I see items sprinkled in the code behind coded like this; the developer is calling the event handler and saturating it with params.
for a DropDownList
ddlAddress.SelectedIndex = 1;
ddlAddress_SelectedIndexChanged(null, new EventArgs());
&
for a RadioButtonList
rblAction.SelectedIndex = 0;
rblActionType_SelectedIndexChanged(null, new EventArgs());
Is this normal coding practice? What should I do as to not disrupt/break the page?
Any thoughts or suggestions would be appreciated.
Thanks,
~ck in San Diego
I would start by removing all of the code from the actual event's method and refactor it into a new method called AddressChanged or whatever else fits your naming standards. You can then call that new function from anywhere else in your code.
protected void ddlAddress_SelectedIndexChanged(object sender, EventArgs e){
AddressChanged();
}
private void AddressChanged(){
//do the changed event
}
private void doingSomething(){
ddlAddress.SelectedIndex = 1;
AddressChanged();
}
Note that you're calling the event handler programatically, not the event.
This can be indicative of a design problem, because usually event handlers should not be relying on each other to execute in a specific order. However, I have seen this pattern and even used it occasionally when code that existed in one event handler needed to be executed in another event handler and could not be refactored at that time. You can set the "sender" to indicate that it's coming from elsewhere in the code and not from the expected control itself, but this is a little bit too opaque to be called a good design.
It would be better practice to refactor out the code that needed to be shared, and put it in a private method, and have both event handlers use it, passing in whatever data from the sender or the eventargs that it needed.