this is more theoretical question. I know that every event in C# has to have 2 parameters: object and eventargs. It's clear. But why does the basic eventargs class even exist when it's impossible to pass any data with it? Of course I can make new EventArgs class that inherits from the basic one, but I just miss the point of the class that can't carry any data.
This is about future-proofing your code.
The theory goes that if at some point you discover that your code should publish more data to event handlers than it did before, you can easily just add more properties to the object you pass to those event handlers.
If, for some reason, the class that holds those data is not under your control you inherit from it, and add your properties to the inherited class. So far so good.
But, if you never passed any object to the event handler in the first place, you cannot add a new parameter to the event delegate without existing code breaking.
As such, that you pass what amounts to a dummy object, EventArgs.Empty to events now give you the ability to later on inherit from EventArgs and start passing data to the same events, without having to change the event handlers at all. I most cases, you don't even have to recompile assemblies that uses the event handler.
So EventArgs is just a handy class you pass to event handlers, you could just as easily create your own, but since it has no meaning except to be a placeholder for possible future changes, there's no need to create your own, simply use EventArgs.
Related
Is there a good strategy to exchange the receiver of multiple events (let's say an object instance A) during runtime to another instance B (or multiple instances)? For example think of a menu bar with a bunch of operations that can be performed on the currently selected of multiple objects.
Now one option would be to connect all object's handlers to the click events and let the handlers filter out the relevant calls (by checking if the current instance is selected) or registering/unregistering the events on selection.
Another one would be to register the events to an object functioning as proxy like this (rough code):
class ClickEventProxy
{
private static ClickEventProxy selectedInstance; // <-- changend on selection
public event EventHandler SomeEventToForward;
public static void RaiseSomeEventToForward(object sender, EventArgs e)
{
if (selectedInstance.ClickedAddNewFrame != null)
selectedInstance.ClickedAddNewFrame(sender, e);
}
...
}
The sender-site would look like SomeSource.Click += ClickEventProxy.RaiseSomeEventToForward; and all receivers would subscribe to their instance of the proxy.
However handling the instances (e.g. by a global <object, proxy instance> dictionary) is a bit unconvenient and the whole thing looks a bit clumsy. So my question: Is there a more programmatic way to do so? Or is it itself bad practice proxying events by introducing another step and one should rather remove and readd the handlers? (Maybe this could be made better by using custom events and altering the invocation list...)
I am trying to understanding the Event Aggregator pattern from an architecture and design view point. I have never used Prism in WPF before, but I'm studying how it works on MSDN.
It seems to me that for every event, the user has to create a new event object that extends the CompositePresentationEvent. It also appears that the new event object has no functionality other than those it inherited from (it usually has no code for itself).
So for example:
A AddNewStuffEvent would look like:
public class AddNewStuffEvent : CompositePresentationEvent<Object> {} //The end of the class
For a HealthChangeEvent:
public class HealthChangeEvent: CompositePresentationEvent<Object> {} //The end of the class
For a BookFlipEvent:
public class BookFlipEvent: CompositePresentationEvent<Object> {} //The end of the class
For a BookCloseEvent:
public class BookCloseEvent: CompositePresentationEvent<Object> {} //The end of the class
And this can go on forever for every little small event for BookOpenEvent, BookTearEvent, etc. So, in a particular namespace folder, there will be a whole ton of event classes, and the Event Aggregator is going to be loaded with all these event objects during runtime. That's, every little small event needs an empty class? Is this how it works? What could be a better way for this?
Yes, every event type needs its own class, which you have to define.
It also appears that the new event object has no functionality other than those it inherited from
The purpose is simply to provide strong typing for the event. This makes it easier to write code to subscribe to them. Ie, the subscribing code can be written like:
aggregator.GetEvent<AddNewStuffEvent>().Subscribe(Handler);
This is a preferable approach to alternatives, such as reliance on "magic strings" in the form of say aggregator.GetEvent("AddNewStuffEvent").Subscribe(Handler) (which could not be verified at compile time.
I'm having a few classes that have one base class named Tool.
In form i have one Tool reference that contains one of the instaces of mentioned classes.
When a MouseDown event occurs on the form i call the current Tool Method ex. "CurrentTool.MethodWhenMouseDown()".
Most of Tools are having 3 methods:
MethodWhenMouseDown()
MethodWhenMouseUp()
MethodWhenMouseMove()
But one or two classes are having just:
MethodWhenMouseDown()
Now which is better:
1.To have all three methods in Tool and the the classes that don't need them just call empty methods.
2.To implement interfaces ex. IMouseMoveListener that would be implemented just by the classes that need to act when MouseMove event occurs. This way if MouseMove event occurs we would ask:
if(CurrentTool is MouseMoveListener)
{
(CurrentTool as IMouseMoveListener).MethodWhenMouseMove();
}
Additional information:
The program is like Ms Paint - the tools are Brush,Bucket(the one that don't need MethodWhenMouseMove),LineTool etc.
In my PaintForm i have one reference of abstrac base class Tool that stores instace one of derived class. The thing that fires event is pictureBox.
Have you considered events to which the tools subscribes? – CodesInChaos
I thougth it would be good practice to have a method in form, that would be called after an evet occurs and the method is calling the siutable method of CurrentTool. ex:
void MouseMoveSubscriber(object sender, MouseEventArgs e)
{
CurrentTool.MethodWhenMouseMove(e);
}
I assume subscribing and unsubscribing the method of CurrentTool each time the CurrentTool was changed a bad practice? I also thought about having all tool refereces in Form and the event would be subscribed by each tool and there would be no need of unsubscrinig. The big drawback in my opinion is that each tool needs to check if it is the CurrentTool.
What you think about it? Thanks for help given.
Performance is not an issue (when the user clicks, the overhead of calling an empty function unnecessarily is of no significance), so this is really about coding ease and code clarity/complexity/maintainability.
So I'd keep it as simple as possible.
I would implement a base class with empty implementations, as this is clean and simple. It requires minimal code in a derived class to get the results you need. It also makes sense (If you don't override the click upcall, you are essentially saying "when a mouse is clicked I wish to do nothing about it").
The next option would be to provide events for mouse up/down/click, and have derived classes subscribe to the events if they wish to. Using events is a standard pattern, but it has the drawback that you have to mess around with the ugly subscription and unsubscription calls. The benefit of this is that if you make them public, these events can be handled by anybody, not just derived classes.
I'd avoid using interfaces and casting - to me this feels like a clunky approach - all it really achieves is fragmenting the "empty functions" approach across a number of different types instead of a simple set of 3 virtual methods. And instead of just calling the methods and knowing they will work, you have to do a lot of type casting and checks first - it just seems messy.
edit
Since you've added some more to the question, I've re-read it and another possibility springs to mind: Create a base Tool class that provides the virtual MouseDown handler that all derived classes need to override. All the normal tools would derive form this.
An additional DragTool class could the derived as an intermediate class that adds the MouseMove and MouseUp handlers that are needed for your special couple of dragging tools.
i.e.
ToolBase (abstract MouseDown)
|
+- ClickTool1
+- ClickTool2
+- DragToolBase (abstract MouseMove + MouseUp)
|
+- DragTool1
+- DragTool2
This would meant there would be no empty implementations in any of your tools.
Without knowing your scenario, I would go with a combination of interfaces and base class:
The base class implements all interfaces with empty virtual methods. The base class is a pure convenience construct. If a tool class wants to inherit from the base class but doesn't need the method it doesn't override it.
In the code that consumes the tools you would work soley with the interfaces. Like this other classes are free to directly implement your interfaces. You gain maximum flexibility like this without any sacrifices.
var mouseMoveListener = CurrentTool as IMouseMoveListener;
var mouseDownListener = CurrentTool as IMouseDownListener;
// ...
if(mouseMoveListener != null)
mouseMoveListener.MethodWhenMouseMove();
if(mouseDownListener != null)
mouseDownListener.MethodWhenMouseDown();
Please note: I used as only instead of is in combination with as.
It depends on actual case. But in your specific case (UI events) I think that have base class with empty handlers (virtual methods) is better than a lot of interfaces. Actually all your tools will inherit from some ToolBase. And invocation code will be smaller and simplier without casting to interfaces.
Alright so. I have an app with several dialogs that have a handful of events that they all respond the same way to, and all have a few methods they provide to the Presenter. These have all been pushed up into a:
public abstract class BaseFormClass : Form
and all the other forms are:
public class DerivedFormClass : BaseFormClass
I've got a model-view-presenter setup going, so the base class has a few protected EventHandler<EventArgs>, and for each one is a similarly named function which is assigned to be called for that event, and a setter exists that the presenter can assign it's own function to be used as the handler for the event. (In other words:)
protected void OnFormBeginClosing(object sender, FormClosingEventArgs e)
{
if (formClosing == null)
return;
formClosing(sender, e);
}
public EventHandler OnFormClose
{
set
{
formClosing = value;
}
}
protected EventHander<EventArgs> formClosing;
Then the presenter uses the OnFormClose setter to set it's own handler function to handle any necessary cleanups or whatever's necessary.
Now that the backstory is out of the way, the main question is, why when I make the simple change of marking the parent Form as abstract does my design view of my child Forms go from the normal design view to just spitting out a mess of HTML (well, not a mess, a single line of what appears to be the entire HTML of the form...)?
Can anyone suggest what I might be doing wrong?
I have never tried this before, but trying the same in Visual Studio 2010, I get the error The designer must create an instance of type 'WinFormsTestApp.FormA' but it cannot because the type is declared as abstract.
I suspect this means exactly what it says - in order to display your derived form, for some reason known only to itself, the designer needs to create an instance of the parent form, and obviously can't do that. Sorry, but you will probably have to redesign your hierarchy. The VS designers make a lot of assumptions about the inheritance patterns used for forms and controls, so if you stray from the standard patterns, these problems are quite common.
Say I have an event defined in an interface.
I then have many classes that implement that interface.
The creation of these classes is managed by StructureMap.
Now say I have one delegate that I want to use as the event handler for ALL of these newly created instances.
Is there a way to tell StructureMap to append an event handler to objects it creates?
(NOTE: My current solution is to create a Notifier class and pass that in through the constructor, which gets the job done, but I'm curious if I can eliminate the middleman.)
If you take a look at http://structuremap.sourceforge.net/Interception.htm there is an explanation to EnrichWith()
Add the the event handler and return the original object and you should have what you want.