这样就可以间接的将TextBox的MouseRightButtonDown事件绑定到Command。
注意:
这种方式相当于将事件映射到Command,CanExecute的返回值只能决定命令是否会被执行,而不能是使得命令目标的可用状态发生改变。以上示例中,输入第一个字母时,命令并没有执行,此时命令无效,但文本框仍然有效,输入第二个字母命令才执行
四、使用MvvmLight行为EventToCommand绑定命令
虽然InvokeCommandAction行为可以将控件的事件转换到Command绑定,也可以通过CommandParameter向ViewModel传递参数,但是对于一些特殊的事件,比如MouseMove,我们需要在事件处理方法中得到鼠标位置信息,使用上面的方式仍不能完成任务;这时我们就需要使用EventToCommand行为,它是MvvmLight封装的行为,要使用行为需要添加GalaSoft.MvvmLight.Extras.dll和System.Windows.Interactivity.dll的引用。
同样,在Blend4中打开解决方案,选中要触发事件的控件 ,在资产面板中选择行为,在列表中选择EventToCommand,双击生成行为,然后设置EventName为MouseMove,然后设置Command绑定,同时需要设置PassEventArgsToCommand="True",也就是将事件参数传递给Command,生成的代码如下:
xaml:
<Grid>
<Ellipse Fill="AliceBlue" Height="180" Stroke="Black" Margin="10,8">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseMove">
<GalaSoft_MvvmLight_Command:EventToCommand PassEventArgsToCommand="True"
Command="{Binding MoveMouseCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Ellipse>
<TextBlock HorizontalAlignment="Center" Text="带事件参数的命令 (鼠标移动事件)"
TextWrapping="Wrap" Grid.Row="7" d:LayoutOverrides="Height"
Grid.ColumnSpan="2" VerticalAlignment="Center"
FontSize="20" FontWeight="Bold"
IsHitTestVisible="False" />
</Grid>
viewmodel:
MoveMouseCommand = new RelayCommand<MouseEventArgs>
(
(e) =>
{
var element = e.OriginalSource as UIElement;
var point = e.GetPosition(element);
CommandResult = string.Format
("执行带MouseEventArgs事件参数的命令,鼠标位置:X-{0},Y-{1}",point.X,point.Y);
}
);
这里命令的初始化方式与带参数的命令一样,只需将参数类型换成事件参数类型
EventToCommand不仅可以用来传递事件参数,他还可以将CanExecute返回值与命令目标的IsEnable属性关联,我们只需将MustToggleIsEnabled的属性设置为True就可以了,示例代码如下:
xaml:
<TextBox x:Name="TextBox2" Text="为空时CanExecute为false" Margin="5,0,5,0" Width="200">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding BehaviourCommand}"
MustToggleIsEnabled="{Binding IsChecked,ElementName=chkMustToggle}"
CommandParameter="{Binding Text,ElementName=TextBox2}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<CheckBox x:Name="chkMustToggle" IsChecked="False"
Content="MustToggleIsEnabled,勾选则TextBox的可用状态与CanExecute返回值关联"/>
五、使用自定义行为绑定命令
如果以上方法都不能满足你的要求,你还可以自定义行为来绑定命令,以下是WPF中自定义行为的代码(SL代码请在文章最后下载示例代码对照阅读):
首先,我们创建一个命令参数类型:
using System;
using System.Windows;
namespace MvvmlightCommand.WPF4.TriggerActions
{
public class EventInformation<TEventArgsType>
{
public object Sender { get; set; }
public TEventArgsType EventArgs { get; set; }
public object CommandArgument { get; set; }
}
}
然后创建行为类:
using System;
using System.Windows;
using System.Windows.Interactivity;
using System.Windows.Input;
namespace MvvmlightCommand.WPF4.TriggerActions
{
public class MapEventToCommand : MapEventToCommandBase<EventArgs>
{
}
public class MapRoutedEventToCommand : MapEventToCommandBase<RoutedEventArgs>
{
}
public abstract class MapEventToCommandBase<TEventArgsType> : TriggerAction<FrameworkElement>
where TEventArgsType : EventArgs
{
public static readonly DependencyProperty CommandProperty =
DependencyProperty.Register("Command", typeof(ICommand),
typeof(MapEventToCommandBase<TEventArgsType>), new PropertyMetadata
(null, OnCommandPropertyChanged));
public static readonly DependencyProperty
CommandParameterProperty = DependencyProperty.Register
("CommandParameter", typeof(object), typeof(MapEventToCommandBase<
TEventArgsType>), new PropertyMetadata(null, OnCommandParameterPropertyChanged));
private static void OnCommandParameterPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var invokeCommand = d as MapEventToCommand;
if (invokeCommand != null)
{
invokeCommand.SetValue(CommandParameterProperty, e.NewValue);
}
}
private static void OnCommandPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var invokeCommand = d as MapEventToCommand;
if (invokeCommand != null)
{
invokeCommand.SetValue(CommandProperty, e.NewValue);
}
}
protected override void Invoke(object parameter)
{
if (this.Command == null)
{
return;
}
var eventInfo = new EventInformation<TEventArgsType>
{
EventArgs = parameter as TEventArgsType,
Sender = this.AssociatedObject,
CommandArgument = GetValue(CommandParameterProperty)
};
if (this.Command.CanExecute(eventInfo))
{
this.Command.Execute(eventInfo);
}
}
public ICommand Command
{
get
{
return (ICommand)base.GetValue(CommandProperty);
}
set
{
base.SetValue(CommandProperty, value);
}
}
public object CommandParameter
{
get
{
return base.GetValue(CommandParameterProperty);
}
set
{
base.SetValue(CommandParameterProperty, value);
}
}
}
}
编译生成项目,在Blend4中打开解决方案,选中要触发事件的控件 ,在资产面板中选择行为,在列表中选择MapRoutedEventToCommand
,双击生成行为,然后设置EventName为TextChanged,然后设置Command绑定,代码如下:
xaml:
<TextBox x:Name="TextBox3" Text="更改文本框的值" Margin="5,0,5,0" Width="200">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<my:MapRoutedEventToCommand Command="{Binding CustomBehaviorCommand}"
CommandParameter="P1"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
viewmodel:
CustomBehaviorCommand = new RelayCommand<EventInformation<RoutedEventArgs>>
(
(ei) =>
{
EventInformation<RoutedEventArgs> eventInfo =
ei as EventInformation<RoutedEventArgs>;
System.Windows.Controls.TextBox sender =
eventInfo.Sender as System.Windows.Controls.TextBox;
CommandResult = string.Format
("执行{0}的TextChanged命令,文本框的值:{1},传递的参数:{2},事件参数:{3}",
sender.Name,
sender.Text,
ei.CommandArgument,
ei.EventArgs.GetType().ToString());
},
(ei) =>
{
return true;
}
);
这样,我们就可以同时将sender、CommandParameter、和事件参数传递到Command的参数中了
本章节主要介绍MvvmLight中命令和事件的处理方法,下章我们将介绍MvvmLight中的Messenger的使用方法,以下是本章源代码下载:
本文来自duanzilin的博客,原文地址:http://blog.csdn.net/duanzilin/archive/2011/05/06/6399640.aspx