Prism库中的InvokeCommandAction(写成prism:InvokeCommandAction)是比较重要的类,相对于Interactivity库中的InvokeCommandAction(写成i:InvokeCommandAction),比较重要的是增加了TriggerParameterPath属性,该属性可以实现将触发命令的事件对象本身或事件对象之属性传递给ViewModel中的命令对象。
TriggerParameterPath是对应于EventArgs中的属性路径,比如用于SelectionChanged事件,则对应于SelectionChangedEventArgs的属性的字符串,如果写 TriggerParameterPath="AddedItems",则指SelectionChangedEventArgs.AddedItems对象。CommandParameter和TriggerParameterPath不同,它就是直接传过去的参数,可以是简单的字符串,也可以是绑定的数据对象。
使用TriggerParameterPath例子
<ListBox Grid.Row="1" Margin="5" ItemsSource="{Binding Items}" SelectionMode="Single"> <i:Interaction.Triggers> <!-- This event trigger will execute the action when the corresponding event is raised by the ListBox. --> <i:EventTrigger EventName="SelectionChanged"> <!-- This action will invoke the selected command in the view model and pass the parameters of the event to it. --> <prism:InvokeCommandAction Command="{Binding SelectedCommand}" TriggerParameterPath="AddedItems"/> </i:EventTrigger> </i:Interaction.Triggers> </ListBox>
在ViewModel中定义命令 public DelegateCommand<object[]> SelectedCommand { get; private set; },即把SelectionChangedEventArgs.AddedItems的值传给DelegateCommand的object[]对象,关于DelegateCommad的创建如下:
public MainWindowViewModel() { // This command will be executed when the selection of the ListBox in the view changes. SelectedCommand = new DelegateCommand<object[]>(OnItemSelected); } private void OnItemSelected(object[] selectedItems) { if (selectedItems != null && selectedItems.Count() > 0) { //Do Work here } }
如果写成TriggerParameterPath=""或者不写TriggerParameterPath属性,则表示把事件对象本身传过去作为CommandParameter,比如如果要传鼠标事件,则就写成TriggerParameterPath=""或不写TriggerParameterPath属性,然后在ViewModel的命令处理程序中
private void OnMouseDownCommandHandler(object mouseDownEventArgs) { if (mouseDownEventArgs != null && mouseDownEventArgs is MouseButtonEventArgs args) { //获取鼠标点的相对位置 Point p= args.GetPosition((IInputElement)args.Source); //这些用到Source对象,代表触发事件的界面元素 } }
使用CommandParameter例子
<ListBox Grid.Row="1" Margin="5" Name="_listBox" ItemsSource="{Binding Items}" SelectionMode="Single"> <i:Interaction.Triggers> <!-- This event trigger will execute the action when the corresponding event is raised by the ListBox. --> <i:EventTrigger EventName="SelectionChanged"> <!-- This action will invoke the selected command in the view model and pass the parameters of the event to it. --> <prism:InvokeCommandAction Command="{Binding SelectedCommand}" CommandParameter={Binding SelectedItem,ElementName=_listBox}/> </i:EventTrigger> </i:Interaction.Triggers> </ListBox>
这个与上面的方法的区别在于,使用了InvokeCommandAction对象的CommandParameter属性传递SelectedItem对象, ViewModel中的代码如下:
public DelegateCommand<object> SelectedCommand { get; private set; } public MainWindowViewModel() { // This command will be executed when the selection of the ListBox in the view changes. SelectedCommand = new DelegateCommand<object>(OnItemSelected); } private void OnItemSelected(object selectedItem) { if (selectedItem != null && selectedItem is string s) { } }
题外话:默认程序会接收 SelectionChangedEventArgs 参数,所以,最好在xaml不写,在 MV 层获取后,自行判断类型和取值