WPF CanExecute depending on more that one factor - c#

I am facing a dilemma in using the CanExecute parameter in CommandBinding for the menu in my application.
The situation is following: the application itself can run in certain modes, e.g. the working mode, review mode, etc. Depending on the mode, some menu items should be enabled or not (hence, should be possible to execute or not).
What I've done until now is create 4 event handlers for CanExecute:
private void Mode1CanExecute(object sender, CanExecuteRoutedEventArgs e);
private void Mode1CannotExecute(object sender, CanExecuteRoutedEventArgs e);
private void Mode2CanExecute(object sender, CanExecuteRoutedEventArgs e);
private void Mode2CannotExecute(object sender, CanExecuteRoutedEventArgs e);
as some menu commands are common to both modes, some are exclusive to each mode.
As the application develops, there are more factors determining whether a particular menu command should be executed at the moment. The solutions I can think of are:
adding a boolean multibinding to CanExecute event handler, but I couldn't find any examples of this solution, I believe it is not possible.
adding more event handlers for CanExecute with even longer names, what will actually make the code less readable
have "per menu item" CanExecute event handler and base the code for each event handler on some boolean variables to determine the result of it
I know that enabling the menu item can be done in SubmenuOpened event handler, but for many of the commands there is also a KeyGesture defined.
My question is: what would be the best practice in this case, so the logic of the application (command execution availability) is guaranteed but also the code readability stays on reasonable level?
Thank you for any suggestions.

Well what I do - is I always have 1 canexecute method per command
This way it's simple and consistent and You know where to look for problem
Another point to have it in 1 method - is just pure testability and readability.
Very simple to test then
public bool CanExecuteGoCommand(){
if (xxx)
return true;
else
return false;
}
and the method can be as big as You want, with as many If's as You need with a million conditions, modes, variables ect..

What I would do is use an implementation of DelegateCommand or RelayCommand as your ICommand property in your ViewModel. Either of these will allow you to pass a Func into the constructor of the ICommand instance as the 'CanExecute' delegate. When you pass this Func in, you could include other properties of your ViewModel as closures, and therefore access them in the delegate. This will allow you to combine your CanExecute parameter with any other member in your ViewModel.

Related

Should I use the Command pattern instead of a call to a static method?

With the hope of learning the Command pattern, I have set up a simple GUI application in C# with two buttons. The first button uses (my attempt at) the Command pattern to perform an operation, whereas the second simply calls a static method in another class.
Here is the form code
private void CommandButton_Click(object sender, EventArgs e)
{
ICommand command = new ConcreteCommand();
command.Execute(); //Performs the same code as DoOperation()
}
private void StaticButton_Click(object sender, EventArgs e)
{
Helper.DoOperation(); //Performs the same code as Execute()
}
My questions are:
Is it appropriate to to implement the Command Pattern in this scenario?
What advantages/disadvantages are associated with using the Command Pattern over static method calls in this specific case? In other, "real world" scenarios?
If my GUI design changes in the future, would it be any more difficult or would it imply more changes to existing code if I used static function calls instead of the Command Pattern?
Command Pattern is used to do set of operations based on the value in command argument, whereas in the code you have shown there is no dependency on the current state. In your case I static method would be fine.
But this wont always be the case so study well your need and then opt for the way to proceed, I would have gone for Command Pattern as this gives more flexibility with future change to requirement.
There is no real advantage of using command pattern in your case. Also, your implementation is incorrect. With command pattern, the one who creates the command is different from one who executes the command. This difference allows you do do some interesting stuff like giving someone else ability to execute the command.
For example, commands are natural part of WPF. There, you can DataBind the command object to the button and leave the actual execution to the button. No need for events or such. Unlike your case, where you have to use events (assuming you are using WinForms)

Calling designer-built event handlers

I'm currently tasked with cleaning up, bug fixing and optimising a Form in winforms (3000 lines of code in one .cs file, it's getting a bit ugly!). I've noticed a few obvious bad practices and some redundant calls already which I could sort out relatively easily.
However there's one that is popping up a lot which seems to me like bad practice, but I can't actually back it up with any documentation. I could be completely wrong.
private void datePicker_DateChanged(object sender, EventArgs e)
{
tabControl_SelectedIndexChanged(sender, e);
}
private void comboBox_SelectedIndexChanged(object sender, EventArgs e)
{
tabControl_SelectedIndexChanged(sender, e);
}
My first concern is that the method will have the sender object that is the date picker or the combo box, but does this matter? I asked myself, what is the sender object there for? Perhaps this is why it's there? I also find EventArgs by itself is pretty useless as far (as I'm aware) unless the class is inherited.
I know that neither the sender or EventArgs are used in the tabControl_SelectedIndexChanged method, so the code works fine. What about possible future implications when some code is changed?
Should I change these to 3 different event handlers that all point to a simple void loadCurrentTab() method? Or perhaps I should get all 3 controls to call the same event handler, such as loadCurrentTab(sender, e)? Or just leave it as it is? Is it that important?
Should I change these to 3 different event handlers that all point to a simple void loadCurrentTab() method?
This would actually be my preference, in this scenario. This makes the intent very clear - all three event handlers are routing to one set of logic which (by design) doesn't pay attention to the sender or EventArgs.
My biggest issue with calling event handlers (aside from it being poor practice) is when you are looking at call stacks with a quick glance, in your case, you would see that the selected index of the tab changes when that did not actually happen.
It's also a good practice to not have unused parameters in your method calls. There are a handful of exceptions (event handling for one) but for any code that I write, I try to be sure I always use what I'm providing.
To start with, it's not all that important. Consider not fixing what isn't broken.
The preferred approach would be to have several handlers all calling a special method (not an eventhandler).
private void datePicker_DateChanged(object sender, EventArgs e)
{
// tabControl_SelectedIndexChanged(sender, e);
RefreshCurrentTabControl();
}
calling other EventHandler is obviously not good pracice. Becouse if tabControl_SelectedIndexChanged change in time and start depend on sender all code fails or star work unexpedted..
I'll separate same logic in third method like you said.. loadCurrentTab(). You also may consider use some command pattern to handle events -> good way to separate Business Logic from GUI.
For example:
interface ICommand {
void Execute();
}
interface IEventCommand : ICommand {
void Execute(object sender, EventArgs e);
}
class CommandAttribute : Attribute {
...
}
class MyCommand : IEventCommand {
...
}
implement some manager, executor, attach command using reflection, etc...
And then you can attach command like this:
[Command(typeof(MyCommand), new [] {"Click"})]
private Button m_oButton = new Button();
All nessesary parameters are auto-magically ;) passed to command.
Yep that's bad practice, you twiddle with one and break the other in ignorance, classic error would be as simple as ((ComboBox)sender).SomeProperty, because "it can only be called from the Combobox".
Depends on how far you can afford to take the refactoring, but my instant reaction would be at least "RefreshTabControl" to do the work and then get the eventHandlers to call it. If you have to expand upon that, ie Sender Or EventArgs matters, then some form of delegation as suggested, or not as clever but much better than what you have, would be an overload.
e.g
void RefreshTabControl(Combobox argBox, EventArgs e)
and then a cast and null check in the eventhandler, at least that would be a statement of intent.
What you have now is a bug waiting to happen.

Naming methods that are registered to events

Assume that I have a class that exposes the following event:
public event EventHandler Closing
How should methods that are registered to this event be named? Do you prefer to follow the convention that Visual Studio uses when it assigns names to the methods it generates (aka. +=, Tab, Tab)? For example:
private void TheClass_Closing( object sender, EventArgs e )
Or do you use your own style to name these methods?
I've tried different ways to name these methods (like TheClassClosing, HandleClosing, etc.). But I haven't found a good style to indicate that the intent of a method is to handle a registered event. I personally don't like the style (underscore) that Visual Studio uses to generate method names.
I know that registered event-handling methods are always private and that there is no naming convention like the one for methods that raise events (e.g., OnClosing).
Name it after what the handler actually does.
// event += event handler
saveButton.Click += SaveData();
startButton.Click += StartTheTimer();
The two common options for naming is either after what the method does:
theObject.Closing += SaveResults;
Or alternatively after what the method handles:
theObject.Closing += ClosingHandler;
Which is preferable really depends a bit on context.
In the first case it is immediately clear what the handler is going to do, which makes the code registering the handler more readable... but looking at the handler SaveResults in isolation it is not going to be necessarily obvious when it is going to be called, unless the event arguments have an obvious name (ClosingEventArgs or some such).
In the second case, the registration is more opaque (okay, so what is going to happen when Closing happens?), but on the other hand, looking at the handler implementation it will be obvious what is going on.
I guess the one to choose depends on which of the two you want to be more obvious; the site of the registration, or the implementation of the handler.
Or alternatively, you can go for the unholy combination of both methods:
theObject.Closing += ClosingHandlerSaveResults;
Now both the registration site and the implementation are equally obvious, and neither looks particularly elegant (plus, it probably violates the DRY principle).
For the record I prefer the first naming scheme when theObject is contained in a different scope from the implementation of SaveResults, and the second scheme when I am wiring up handlers to events that are all contained within the same class.
I name my event handlers similarly to those created by Visual Studio (the +,=,tab,tab you mention). I try to keep my naming consistent in my code, and I know that I will be creating handlers with the VS auto-creator at least some of the time.
The underscores don't bother me.
maybe: OnObjectNameEventName, such as
private void OnTheClassClosing(object sender, EventArgs e)
This matches the internal event methods, and with the addition of the object name, it should help differentiate, besides, the method to raise events are essentially internal event handlers
User clicks form, form calls OnClicked, does its thing, then raises the Clicked event, it would only be natural from my point of view.

What use cases exist for non-static private or protected events?

What purpose do protected or private (non-static) events in .NET really serve?
It seems like any private or protected event is more easily handled via a virtual method. I can (somewhat) see the need for this in static events, but not for normal events.
Have you had a use case before that clearly demonstrates a need or advantage for a non-static protected or private event?
Here's a slightly bizarre but real-world scenario I implemented once. You have machine-generated and user-generated halves of a partial class. The machine-generated half contains code which wishes to inform the user-generated half when some event occurs. But the user-generated half might not care to do anything, or it might care to do rather a lot. It seems rude of the machine-generated half to require that the user-generated half implement a particular method in order to handle a message they don't have any interest in listening to.
To solve this problem, the machine-generated half could fire on a private event. If the user-generated half cares, it can subscribe the event. If not, it can ignore it.
This scenario is now addressed more elegantly by partial methods in C# 3, but that was not an option back in the day.
Seems to me that a good example of where a private event is useful is in component/control building, often you may have a component that is a composite of 1 or more other components, private events that contained components can subscribe to is a handy and easy implementation of an observer pattern.
Edit:
Let me give an example...
Say you are writing a Grid type control, and inside of this control you would most likely have a bunch of contained classes that are created dynamically Rows, Cols, headers etc for example, say you want to notify these contained classes that something they care about has happend, say a Skinning change or something like that, something that you don't necesarrily want to expose as an event to the grid users, this is where private events are handy, simply have one or 2 handlers and as you create each instance of your row or col or whatever attach the handler, as otherwise you just have to write your own observer mechanism, not hard, but why when you dont have to and you can just use multicast events.
Nested types have access to the enclosing type's private and protected events. I've used this feature to notify child controls (the nested type) of state changes in the parent control (the enclosing type) in a Silverlight application.
Sorry to drag up an old thread, but I use private events with impunity in one of my projects, and personally, I find it's a good way of solving a design issue:
Here's the abbreviated code:
public class MyClass
{
private event EventHandler _myEvent;
public ExternalObject { get; set; }
public event EventHandler MyEvent
{
add
{
if (_myEvent.GetInvocationList().Length == 0 && value != null)
ExternalObject.ExternalEvent += HandleEvent;
_myEvent+= value;
}
remove
{
_myEvent-= value;
if (_myEvent.GetInvocationList().Length == 0)
ExternalObject.ExternalEvent -= HandleEvent;
}
}
private void HandleEvent(object sender, EventArgs e)
{
_myEvent.Raise(this, EventArgs.Empty); // raises the event.
}
}
Basically, MyEvent is only ever raised in the event handler of ExternalObject.ExternalEvent, so if there's no handlers for MyEvent then I don't need to attach a handler to the external event, speeding up the code slightly by saving a stack frame.
Not only the current instance can access a private member. Other instances of the same type can too! This enables some scenarios where this access control may be useful.
I am thinking of a tree structure where all nodes inherit a certain type and a private/protected event allows to propagate leaf events to their parents. Since they are the same type, the parent can register to the child's private event. Yet any client of the tree structure cannot.
I can definitely see a use case in a directory like storage system where where each directory needs to propagate its last modified date to its parent for example.

Is the "sender" in Button_Click(object sender... really the sender?

Ted Faison in a podcast on event-based software design mentioned that "sender" and "self" objects in .NET, C++ and Java event statements such as:
private void Button_Click(object sender, RoutedEventArgs e)
are a misnomer since e.g. in the above example "sender" is not really the object which produced the event but a proxy, since you wouldn't want to couple your applications that tightly.
Did I understand him incorrectly (since when I debug it, "sender" does indeed seem to be the original object).
Or is it that common event patterns in these languages (e.g. a common click handler) are tightly coupled but they should be more decoupled, e.g. in composite applications.
He also mentioned that e.g. you shouldn't make inherit from EventArgs since it leads to an explosion of classes, one per event, which only transport a few variables. Many times in his opinion, you can just send a string for instance. He mentioned that this opinion is the opposite of what Microsoft Patterns and Practices suggests.
Any thoughts on these areas?
In most cases, sender is the Button (or whatever) that raised the event. There are some occasions when this isn't the case - such as a (perhaps lazy) pass-thru event:
class Foo {
private Bar bar;
public Foo(Bar bar) {
this.bar = bar;
}
public event EventHandler SomeEvent {
add {bar.SomeEvent += value;}
remove {bar.SomeEvent -= value;}
}
//...
}
Here, if we subscribe to foo.SomeEvent, we will actually get back the event originated by the Bar instance - so sender won't be foo. But this is arguably because we've implemented Foo.SomeEvent incorrectly.
To be honest, in most cases you don't need to check sender; the main time this is useful is when a number of controls share a handler. You should generally be able to assume the sender is the instance you subscribed to (for the purposes of reference-equality tests).
Re EventArgs - the standard pattern (when creating a new event-type) would recommend you to inherit from this. I don't recommend deviating from this. A minor reason is that it allows you to use EventHandler<T>, but there are other variance reasons too. Besides - sometimes doing what other people expect is reason enough; people expect an EventArgs derived value.
That said - I have done non-standard events before (in MiscUtil's Push LINQ) - but this was already in a very unusual setup, so it didn't feel out of place.
First - the 'sender' will hold a reference to the button you clicked. If you have multiple buttons all hooked to the same event, this is how you see which one of the buttons you hit (if you're not passing something in the event arguments to read this).
Also I do to some extend agree that writing new eventargs inheriting frmo EventArgs can lead to explosion of classes - so use with causion. I like just raising an EventArgs.Empty and then have the code catching the event explicit querying the object that raised the event for the data. What i mean is - once you catch the event, instead of reading the data from the event arguments you go to the object that raised the event and read those of its properties you are interrested in. This makes it easier to just read what you need, but ofcourse - you could find yourself in a situation where those properties changed between the event raised and you reading the properties.

Categories

Resources