I try to use commands with the MVVM - Pattern and I don't know how to "bind" a command to a special event, e.g. MouseUp or MouseEnter. How to do this?
Asked
Active
Viewed 972 times
1
-
2use `EventToCommand` behavior from MVVM light: http://www.galasoft.ch/mvvm/ – Bolu Oct 30 '13 at 12:13
-
1If you don't want to use MVVM Light, Blend has a similar behavior. – trinaldi Oct 30 '13 at 12:25
-
@Tico - could you be so kind as to explain that behavior and how to use it please? – Immortal Blue Oct 30 '13 at 13:40
-
@ImmortalBlue Open you project on Blend. Go to `Behaviors` there's one called `InvokeCommandAction`. What it does is "transform" an event to a Command. As an example I'll show what I did (I'll use pastebin: http://pastebin.com/3mbxzagp) – trinaldi Oct 30 '13 at 15:29
-
Please check an answer or add more help to us – Krekkon Mar 15 '14 at 09:20
4 Answers
3
First you should define ICommnad
property in your ViewModel
.
public ICommand MouseUpCommand
{
get
{
if (this.mouseUpCommand == null)
{
this.mouseUpCommand = new RelayCommand(this.OnMouseUp);
}
return this.mouseUpCommand;
}
}
private void OnMouseUp()
{
// Handle MouseUp event.
}
You can find lot of ICommand
implementations. One of them:
public class RelayCommand : ICommand
{
public RelayCommand(Action<object> execute)
{
this._execute = execute;
...
}
...
public void Execute(object parameter)
{
_execute(parameter);
}
}
Then add event trigger within which invoke your Command
:
<i:EventTrigger EventName="MouseUp">
<i:InvokeCommandAction Command="{Binding MouseUpCommand}"/>
</i:EventTrigger>

Anatolii Gabuza
- 6,184
- 2
- 36
- 54
-
If i don't use ICOMMAND, relaycommand and just declare the mousedown in code behind file of respective view, can that be considered as MVVM implementation? – Sangram Nandkhile Oct 30 '13 at 12:42
-
2@Sangram No. Any time you use code behind - it's not proper MVVM. And obviously there cannot be a MVVM without `ViewModel`. – Anatolii Gabuza Oct 30 '13 at 13:03
-
@AnatoliiG, that's absolute crap - MVVM is intended to REDUCE code behind, but saying code behind = not MVVM is not true. See http://channel9.msdn.com/blogs/kreekman/techdays-2010-understanding-the-model-view-viewmodel-pattern at 01:01:00 – Immortal Blue Oct 30 '13 at 13:25
-
Also, your view model should be UI agnostic, (Although I appreciate that this is just an example, obviously!) but you should label things as a functional level at the command level. For example, the command should be called RefreshMenu or whatever it is functionally bound to, so if you want to call that command from somewhere else, you don't end up with a menu item pointing to a "MouseUp" command. – Immortal Blue Oct 30 '13 at 13:42
-
@ImmortalBlue Read my comment again. I just told that it's not "proper" MVVM. And if you have some experience with xaml and MVVM then you should agree that every time you see code-behind it's something done in fast and dirty way. Usually not testable, hard to refactor, maintain etc. – Anatolii Gabuza Oct 30 '13 at 14:03
-
I disagree with the it's not "proper" MVVM, when used properly, it can be perfectly acceptable and still "proper" MVVM. But yes, it's one of those things that can be easily abused, and there are times I've seen it done and it's made kittens cry, but equally, I've seen cases where people have bent over backwards to avoid code behind and implemented factories which then get instantiated somewhere in xaml, when two lines of code behind would have solved their problems. – Immortal Blue Oct 30 '13 at 14:12
0
Look at WPF Binding UI events to commands in ViewModel.
For this you need System.Windows.Interactivity.dll
which you can get from Nuget
0
Completing @AnatoliiG post here's an implementation and a sample usage of the RelayCommand
class.
Code:
public class RelayCommand : ICommand
{
#region Fields
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
#endregion // Fields
#region Constructors
public RelayCommand(Action<object> execute)
: this(execute, null)
{
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
#endregion // Constructors
#region ICommand Members
[DebuggerStepThrough]
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
_execute(parameter);
}
#endregion // ICommand Members
}
Usage:
// To use this class within your viewmodel class:
RelayCommand _myCommand;
public ICommand MyCommand
{
get
{
if (_myCommand == null)
{
_myCommand = new RelayCommand(p => this.DoMyCommand(p),
p => this.CanDoMyCommand(p) );
}
return _myCommand;
}
}