0

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

有人可以解释如何将以下 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; 
    } 
} 
4

3 回答 3

1

你有几个选择:

  1. 在 XAML 中附加事件处理程序,但事件处理程序唯一要做的就是调用视图模型并传入适当的参数(重要的是不要将任何 GUI 级别的项目传递给视图模型——只传递执行操作所需的数据)

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

只要您不尝试在样式或模板中设置这些事件处理程序,我建议您采用选项#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();
        }
    } 
} 
于 2011-10-19T03:10:05.993 回答
1

关于 MVVM 的经验法则很少......

  1. 你的Models并且ViewModles不应该引用System.Windows.Controls命名空间。
  2. 你的Models并且ViewModles不应该处理事件。为此使用ICommand接口。
  3. RoutedCommand在模型/视图模型中无效(由于第 2 点)。因此使用DelegateCommand /RelayCommand

话虽如此,如果您在MVVM中编写了附加行为,则上述所有要点都是完全允许的。

于 2011-10-19T04:58:36.160 回答
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]" />
于 2011-10-19T05:50:00.627 回答