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

发布于 2024-12-10 23:22:09 字数 927 浏览 0 评论 0原文

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

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

I am trying to translate WPF CodeBehid events like Event, Handler, EventSetter to MVVM pattern. I am not allowed to use System.Windows.Controls since I am using MVVM. And I am also avoiding 3rd party library to solve this issue.

Can somebody explain how to convert the following CodeBehind Event Handler to MVVM Event-Handler? Please explain as much as you can while writing answer.

XAML Code

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

Code Behind

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; 
    } 
} 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

谁人与我共长歌 2024-12-17 23:22:09

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

  1. 您的 ModelsViewModles 不应引用 System.Windows.Controls 命名空间。
  2. 您的 ModelsViewModles 不应处理事件。为此,请使用 ICommand 接口。
  3. RoatedCommand 在模型/视图模型中无效(由于第 2 点)。因此使用 DelegateCommand / RelayCommand

话虽如此,以上几点都是如果您编写了附加行为<,则完全允许 /strong> 在MVVM

There are few thumb rules regarding MVVM....

  1. Your Models and ViewModles should not refer System.Windows.Controls namespace.
  2. Your Models and ViewModles should not handle events. Use ICommand interface for that.
  3. RoutedCommand is not valid in Models / ViewModels (due to point 2). Hence use DelegateCommand / RelayCommand

Having said that, all the above points are perfectly allowed if you have written an Attached Behavior in MVVM.

心不设防 2024-12-17 23:22:09

您有几个选择:

  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();
        }
    } 
} 

You have a couple of choices:

  1. Attach the event handler in XAML but the only thing the event handler does is call into the view model passing in the appropriate arguments (it's important not to pass any GUI level items to the view model -- just the data necessary to perform the action)

  2. Use the EventToCommand behavior (showcased here) to attach an instance of an ICommand (from your view model) to an event in your view

As long as you're not trying to set these event handlers up in styles or templates I would recommend pursuing option #1 -- there is no iron law prohibiting you from using event handlers when convenient, as long as the view model is what actually performs all the work

Edit: Option #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();
        }
    } 
} 
幸福丶如此 2024-12-17 23:22:09

您还可以使用 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]" />

You can also use Caliburn Micro libraries to be able to attach a handler in ViewModel to an event in View.

Sample code:

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

 <Button Content="Edit" DataContext="{Binding Path=VmInstance}" 
             cal:Message.Attach="[Event Click] = [Action EditFilter]" />
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文