如何翻译CodeBehind WPF事件;事件,处理程序,EventSetter到MVVM模式?

时间:2011-10-19 02:56:00

标签: wpf events mvvm eventargs

我正在尝试将WPF CodeBehid事件(如Event,Handler,EventSetter)转换为MVVM模式。因为我使用MVVM,所以不允许使用System.Windows.Controls。我也在避免第三方库来解决这个问题。

有人可以解释如何将以下CodeBehind事件处理程序转换为MVVM事件处理程序吗?请在写答案时尽可能多地解释。

XAML代码

<DataGridCheckBoxColumn Header="Select" Binding="{Binding Path=IsSelected}"> 
  <DataGridCheckBoxColumn.CellStyle> 
    <Style TargetType="DataGridCell"> 
      <EventSetter Event="MouseLeftButtonUp" Handler="ApprovedMouseUp"></EventSetter> 
    </Style> 
  </DataGridCheckBoxColumn.CellStyle> 
</DataGridCheckBoxColumn> 

代码背后

private void ApprovedMouseUp(object sender, MouseButtonEventArgs e) 
{ 
    if(sender is DataGridCell) 
    { 
        var temp = (sender as DataGridCell).Content; 
        if(temp is CheckBox) (temp as CheckBox).IsChecked = !(temp as CheckBox).IsChecked; 
    } 
} 

3 个答案:

答案 0 :(得分:1)

您有几个选择:

  1. 在XAML中附加事件处理程序,但事件处理程序唯一做的是调用视图模型传递适当的参数(重要的是不要将任何GUI级别的项目传递给视图模型 - 只是数据

  2. 使用EventToCommand行为(此处显示)将ICommand的实例(从您的视图模型)附加到视图中的事件

  3. 只要您不尝试在样式或模板中设置这些事件处理程序,我建议您选择#1选项 - 只要视图模型,就没有铁法禁止您在方便的时候使用事件处理程序是实际执行所有工作的

    编辑:选项#1

    private void ApprovedMouseUp(object sender, MouseButtonEventArgs e) 
    { 
        if(sender is DataGridCell) 
        { 
    
            var checkBox= (sender as DataGridCell).Content as CheckBox; 
            if(checkBox != null) 
            {
                var viewModel = (MyViewModel)checkBox.DataContext;
                viewModel.ToggleApprovedStatus();
            }
        } 
    } 
    

答案 1 :(得分:1)

关于MVVM的拇指规则很少......

  1. 您的ModelsViewModles不应该引用System.Windows.Controls名称空间。
  2. 您的ModelsViewModles不应处理事件。使用ICommand界面。
  3. RoutedCommand在Models / ViewModels中无效(由于第2点)。因此,请使用DelegateCommand / RelayCommand
  4. 话虽如此,如果您在 MVVM 中写了 Attached Behavior ,则上述所有要点都完全允许

答案 2 :(得分:1)

您还可以使用Caliburn Micro库将ViewModel中的处理程序附加到View中的事件。

示例代码:

 ...  xmlns:cal="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro"....

 <Button Content="Edit" DataContext="{Binding Path=VmInstance}" 
             cal:Message.Attach="[Event Click] = [Action EditFilter]" />