When should I use the Command and when to use the Click event?
F.e. if I have a Button in my UWP app what should I use?
When should I use the Command and when to use the Click event?
Yours is a broad question and I would simply answer with: "It depends".
Because:
The Command implements the ICommand interface and this means more code to add to your application but usually this won't change. Instead, the event handler doesn't require any interface implementation.
For every command you want, you have to provide the code that will handle the click and the CanExecute logic, to say when the command can execute. This is not requested in a simple event handler (like MyButton_Click). This means that, using a Command, you will have more control over the elements of your UI (the button won't execute anything if CanExecute is false).
When you want to add a Command, you will bind it to your DataContext (the ViewModel, if you implement the MVVM pattern). Instead, when you add a simple event handler (like MyButton_Click), the code will be placed in your code-behind that is the logic behind your main window. This means that implementing a Command, according to me, you'll have everything you need to modify in just one place (the ViewModel) instead of logic scattered everywhere in your project.
Of course, you can use whatever you want and my points are there just to give you an insight about these different implementations and you have to consider which solution is suitable for you, considering also the requirements you have been given (like: "Don't use event handlers" or "The Command is too advanced, let's just use something simple", etc.) and/or other constraints in your project.
Related
I'm trying to perform some actions at my VM just before my Window closes, It mean I need DataContext must be available for my actions.
Actually I'm trying with this:
<i:Interaction.Triggers>
<i:EventTrigger EventName="Closing">
<cmd:EventToCommand Command="{Binding _MyCleanUpCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
But, at this point all objects on my ViewModel are cleaned and my DataContext = null
What is the propper event to Bind with my command?
There is a way to force one class to execute Automatically a method when this is no needed anymore (Needed mean in my current proccess)?
NOTE: For the second question IDisposable does'nt work due must be called manually. ~ Finalizers doesn´t work inmediatelly.
First of all the objects are not being cleaned.
The name of the event you are trying to listen to is called "Closing" which is being fired before the actual close. The event that signals to you that a window got completely closed is called "Closed". Those are the two events available for you.
I would simply associate the handler in the View constructor
MyWindow()
{
// Set up ViewModel, assign to DataContext etc.
Closing += viewModel.OnWindowClosing;
}
Then add the handler to the ViewModel:
public void OnWindowClosing(object sender, CancelEventArgs e)
{
// Handle closing logic, set e.Cancel as needed
}
In your case, you gain exactly nothing except complexity by using a more elaborate pattern with more indirection (5 extra lines of XML plus command pattern).
The "zero code-behind" mantra is not the goal in itself, the point is do decouple ViewModel from the View. Even when the event is bound in code-behind of the View, the ViewModel does not depend on the View and the closing logic can be unit-tested.
However if you insist on sticking to interaction I recommend you read this link below:
http://msdn.microsoft.com/en-us/library/ms748948.aspx
It will give you an overview about events of Window.
Btw, like I already said DataContext is there for sure so I assume you rather have a bug somewhere in Command pattern (you might have defined the Command wrong). You should have posted us the complete code.
Futhermore giving names to public commands with first letter being an underscore is sooo outdated. I remember using them 20 years ago in pure C to signal a private field. :)
Your DataContext and all other objects shouldn't be already cleaned when you enter into your Closing command. This is not the expected behavior.
Indeed, the main purpose of the Closing event is to provide a way of preventing the application exit without any harm (from msdn):
When a window closes, it raises two events: Closing and Closed.
Closing is raised before the window closes, and it provides a
mechanism by which window closure can be prevented. One common reason
to prevent window closure is if window content contains modified data.
In this situation, the Closing event can be handled to determine
whether data is dirty and, if so, to ask the user whether to either
continue closing the window without saving the data or to cancel
window closure. The following example shows the key aspects of
handling Closing.
Chances are there's a bug with your EventTrigger which triggers the associated command too late in this particular scenario.
Try to simply bind your window to the Closing event in code behind and see what happens.
I read all about WPF commanding and i understand the GoF Command Pattern, still thought, i have one question about the process: how does the command target (for example a text box) tell the command source ( a button for instance) that it has changed state (eg. some text inserted into the textbox) so that the source can disable or enable itself or what ever it wishes to do. to put it in another way, how does the command target let the ICommand implementing class (the cut command for example) to trigger it's CanExecuteChangedEvent so that class can in turn let the command source know about state changes.
There is a class called CommandManager taking care of execution logic. You can call CommandManager.InvalidateRequerySuggested method to let system check your CanExecute methods.
I have a co-worker that asked me why he has to use the ICommand pattern.
He wants to add a button and then make an event for it in the code behind. Then from the event he wants to call a method on the ViewModel.
I gave him the obvious answer: This adds coupling between the View and the ViewModel. But he argued that the View and the ViewModel are already coupled. (We set our view's DataContext to the ViewModel in the View's code behind: DataContext = new MyViewModel();
Yes, I told him that his way adds "more coupling", but it sounded a bit lame even to me.
So, I know that ICommand is the clean way, and I do it that way. But what else does ICommand buy you besides not using an already existing coupling?
It's not about decoupling, but how deep you can penetrate inside your ModelView hierarchy: not event pumping, but event routing, built-in in the framework.
It's about UI managent: Command has state (CanExecute), if assign the command to the control, if command's state becomes false, control becomes disabled. It gives you powerful UI state management way, avoiding a lot of spaghetti coding, for complicated UI especially.
I have a co-worker that asked me why he has to use the ICommand
pattern.
It seems implied this is a standard at your company (whether explicitly stated or unspoken). That should be answer enough to his question.
If all company code is supposed to use that pattern, it can cause co-developer confusion and frustration when someone else has to debug his code.
Also, in my opinion, using ICommand is faster to develop / mock up because you don't NEED to have the ICommand property on the context to run your program. It lets your UI designers (if you are lucky enough to have them) completely finish their tasks even if you are behind in your coding.
ICommand can also give you a place for handling wether or not a specific button can be used right then. this would be handled through the canexecute method.
You can bind the CanExecute method of the command to the properties of a control, also a Command encapsulates an action in a nice way. In my opinion / experience this approach makes a lot of sense because you have both the condition and the execute action in a single abstraction, which makes it easier to understand and test.
If in the future you find that this action is repeated you can abstract it easily in your own custom ICommand and use it in several places.
One thing that I don't see in the previous answers is that using the ICommand promotes code reuse by allowing the same action to be used by different GUI components. For example, if I had a command that should result in the opening of a window and that command could be invoked in three or for different screens in the application, an ICommand implementation lets me define that logic in a single place. With the code-behind event handlers, I have to copy and paste redundant code, in violation of DRY (or else, I'd have to roll my own implementation by abstracting out to a class, at which point, I might as well use ICommand).
So I followed the guide on the following site to restrict the characters a textbox can accept.
http://www.rhyous.com/2010/06/18/how-to-limit-or-prevent-characters-in-a-textbox-in-csharp/
My problem is I can't figure out how to make the event handler trigger in the secondary class. Basically how do I tell VS to look for the event handler code in that class instead of MainWindow? I tried searching, but apparently don't know the correct terms to use. The xaml reference I used was
xmlns:DigitBox="clr-namespace:System.Windows.Controls;assembly=PresentationFramework"
Any ideas?
Simplest way I've found to do it is assign the event in your constructor.
public MainWindow()
{
InitializeComponent();
TextBoxCurrency.GotFocus += expandedTextBoxEvents.TextBoxCurrencyGotFocus;
TextBoxCurrency.LostFocus += expandedTextBoxEvents.TextBoxCurrencyLostFocus;
}
I've searched a way to do it in XAML and I did not found an easy and clean way to do it.
You are much better off using commands and command bindings. I'm not sure what the specific command that would would bind to for a text box for your desired functionality, but one of the goals for WPF was to lessen the use of Event Handlers in code behind.
Check out this article for an overview of commands and this article for a way to hook up commands with events. WPF commanding is one of the coolest features to enable true separation of concerns between UI and business logic.
As a worst case scenario solution, you could create your own text box that inherits from the text box control and hook up the events in that class. Your control would then be reusable.
The WPF CommandManager allows you to do the following (pseudo-ish-code):
<Button Name="SomeButton" Command="{Binding Path=ViewModelCommand}"/>
And in the code-behind:
private void InitCommandEvents()
{
CommandManager.AddExecutedEventHandler(this.SomeButton, SomeEventHandler);
}
The SomeEventHandler never gets called.
To me this didn't seem like something very wrong to try and do, but if you consider what happens inside CommandManager.AddExecutedEventHandler, it makes sense why it doesn't. Add to that the fact that the documentation clearly states that the CommandManager only works with RoutedCommands.
Nonetheless, this had me very frustrated for a while and led me to this question:
What would you suggest is the best workaround for the fact that the CommandManager does not support custom ICommands? Especially if you want to add behavior around the execution of a command?
For now, I fire the command manually in code behind from the button click event.
I generally just subclass RoutedCommand and re-use its functionality instead of implementing an ICommand from scratch. Then it works well with CommandManager, etc, and everyone is happy.
On the other hand, if you do implement an ICommand from scratch, it seems to me that there's no need of CommandManager.AddExecutedEventHandler: Your custom ICommand can easily expose its own way of registering for notifications when the command executes. In fact, most custom ICommand implementations do this as the primary way of handling command execution.
Either way it doesn't seem you would ever need both custom ICommand functionality and CommandManager support at the same time.