Whilst programming Java GUis I made heavy use of the Action class. The instantiated action class was passed to numerous button or menu item constructors so that you only had to code the logic in one place.
Each time you clicked on a button/icon/menuitem associated with the action the actionPerformed method would fire and execute the code.
This was a great time saver and allowed me to write the logic only once.
Questions:
Is there a similar class in C# or .NET framework?
Have I got this all wrong and there is a different way to have one set of logic called from multiple buttons/icons/menuitems?
.Net uses events heavily and you can do something like this if you have common functionality.
protected void button_click(object sender, EventArgs e)
{
// Common code here
// You can use sender parameter to distinguish b/w the buttons.
}
and
button1.Click += button_click;
button2.Click += button_click;
button3.Click += button_click;
C# usually uses events to associate behavior with user actions. You can use a single event handler to handle the click on several buttons or menu items.
BTW, C# is a language, not a GUI framework. There are several GUI frameworks that you can use with C# (Windows Forms, WPF, Silverlight, ASP.NET), and each one is different. So your question isn't really related to C#, but rather to one of these frameworks.
Related
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
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
}
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
}
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.
Lets say we have a form consisting of 20+ controls, for example buttons.
We want to create handlers for the On-click event for all of them.
The usual way is to go to the designer and double-click each button to have it automatically create the function.
Another way is to create them yourself in code, after the InitializeComponent() function.
Is the difference between the two?
1) In performance
2) In speed
3) Garbage collecting
The first way is easy but lately I've been thinking about the second because its easy to see (in one place) what controls have what events handled without going to the designer which is a real pain if you have the controls cluttered...
Creating them through the designer is exactly the same as defining them in code yourself.
What actually happens is they are placed within the InitializeComponent() method on the form, which is normally in the designer.cs file. So it's there, it's just a little more hidden from the developer.
This means that neither performance/speed nor garbage collection will be affeted in anyway :)
As the other answers stated, there is little to choose between the tow methods other then coding style.
I have worked on a project where the Buttons themselves were attributed data that allowed a generic event handler to determine the action required. This alows the Event Handler code to be nice and simple e.g.
foreach(Control ctrl in this.Controls)
{
if(ctrl is Button)
{
(ctrl as Button).Click += // generic Event handler
}
}
The downside of this approach is that it tightly couples the button with the event handler code. But in a limited scope application with a set of buttons that perform the same function, this could be a useful techinque.
There's no difference in performance speed or garbage collection. Whether you write the event hander button.OnClick += MyHandler or you double click in the designer and he generates that for you, it's just the same.
There might be a difference in typing button.OnClick += MyHandler and the Visual Studio generated button.OnClick += new EventHandler(MyHandler). Since there's a constructor involved. But that's just a marginal difference.
Why would there be any difference ?
When you doubleclick the button in the designer, to create an eventhandler, VS.NET will generate code to attach the eventhandler to the Click event.
Actually, the generated code will be the same as the code that you'll write to attach the eventhandler to the event.