我应该把所有的事件在视图代码后面或有一个更合适的方式,如放置命令在ViewModel?例如,我想在数据网格行上双击打开Tab,我应该在哪里处理此事件?
不,你不应该把事件放在代码后面。在MVVM (model - view - viewmodel)设计模式中,视图模型是负责处理应用程序的表示逻辑和状态的组件。这意味着视图的代码隐藏文件不应该包含处理从任何用户界面(UI)元素引发的事件的代码。
for example如果你在xaml中有button
<Button Content="OK" Click="btn_Click"/>
protected void btn_Click(object sender, RoutedEventArgs e)
{
/* This is not MVVM! */
}
您可以使用WPF命令。你所要做的就是绑定到它的Execute和CanExecute委托并调用你的命令。
所以你的代码现在是public class ViewModel
{
private readonly DelegateCommand<string> _clickCommand;
public ViewModel()
{
_clickCommand = new DelegateCommand(
(s) => { /* perform some action */ }, //Execute
null
} //CanExecute );
public DelegateCommand ButtonClickCommand
{
get { return _clickCommand; }
}
}
<Button Content="COOL" Command="ButtonClickCommand"/>
Kyle是正确的,您的处理程序应该出现在视图模型中。如果命令属性不存在,则可以使用交互触发器:
<DataGrid>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<i:InvokeCommandAction Command="{Binding Mode=OneWay, Path=OpenClientCommand}" CommandParameter="{Binding ElementName=searchResults, Path=SelectedItems}" />
</i:EventTrigger>
</i:Interaction.Triggers>
... other stuff goes here ...
</DataGrid>
或者你可以使用MVVM Lite的EventToCommand,它也允许你传递消息参数:
<i:Interaction.Triggers>
<i:EventTrigger EventName="Closing">
<cmd:EventToCommand Command="{Binding ClosingCommand}" PassEventArgsToCommand="True" />
</i:EventTrigger>
</i:Interaction.Triggers>
在这种情况下用于取消窗口关闭事件,以响应"您确定要退出吗?"对话框:
public ICommand ClosingCommand { get { return new RelayCommand<CancelEventArgs>(OnClosing); } }
private void OnClosing(CancelEventArgs args)
{
if (UserCancelsClose())
args.Cancel = true;
}
相关命名空间如下:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd ="http://www.galasoft.ch/mvvmlight"