【问题标题】:A good aproach to events in MVVMMVVM 中处理事件的好方法
【发布时间】:2010-12-05 03:00:46
【问题描述】:

所以我在尝试实现 MVVM 时遇到了这个问题。 AFAIK 在 ViewModel 类中执行方法的最佳方式是通过 CommandBinding。

<Button Command={Binding DoSomethingCommand} />

只有这一次我需要对 ListBoxItem 进行双击操作,而 ListBoxItem 没有实现 ICommandSource。所以我想知道最好的方法是什么,如果有的话。

谢谢!

编辑:

我只是想到了一种方法,但它似乎相当hacky。如果我公开 ListBox.DoubleClick 事件,并且我的 ViewModel 类订阅它并在 DoubleClick 被触发时运行正确的方法怎么办?

【问题讨论】:

    标签: wpf events mvvm command


    【解决方案1】:

    您可以在 代码隐藏 文件中处理事件并调用 ViewModel 对象上的方法。在我看来,这比开始破解要好得多。 :-) 我不会将 WPF 路由事件传递给 ViewModel 对象。

    谁说禁止使用代码隐藏? Model-View-ViewModel 模式绝对不是。

    【讨论】:

      【解决方案2】:

      Silverlight 不包含像 WPF 中的按钮那样的命令按钮。我们绕过它的方法是创建一个包含命令并将该事件映射到命令的自定义控件。这样的事情应该可以工作。

      public class CommandListBoxItem : ListBoxItem
      {
          public CommandListBoxItem()
          {
              DoubleClick += (sender, e) =>
              {
                  if (Command != null && Command.CanExecute(CommandParameter))
                      Command.Execute(CommandParameter);
              };
          }
      
          #region Bindable Command Properties
      
          public static DependencyProperty DoubleClickCommandProperty =
              DependencyProperty.Register("DoubleClickCommand",
                                          typeof(ICommand), typeof(CommandListBoxItem),
                                          new PropertyMetadata(null, DoubleClickCommandChanged));
      
          private static void DoubleClickCommandChanged(DependencyObject source, DependencyPropertyChangedEventArgs args)
          {
              var item = source as CommandListBoxItem;
              if (item == null) return;
      
              item.RegisterCommand(args.OldValue as ICommand, args.NewValue as ICommand);
          }
      
          public ICommand DoubleClickCommand
          {
              get { return GetValue(DoubleClickCommandProperty) as ICommand; }
              set { SetValue(DoubleClickCommandProperty, value); }
          }
      
          public static DependencyProperty DoubleClickCommandParameterProperty =
              DependencyProperty.Register("DoubleClickCommandParameter",
                                          typeof(object), typeof(CommandListBoxItem),
                                          new PropertyMetadata(null));
      
          public object DoubleClickCommandParameter
          {
              get { return GetValue(DoubleClickCommandParameterProperty); }
              set { SetValue(DoubleClickCommandParameterProperty, value); }
          } 
      
          #endregion
      
          private void RegisterCommand(ICommand oldCommand, ICommand newCommand)
          {
              if (oldCommand != null)
                  oldCommand.CanExecuteChanged -= HandleCanExecuteChanged;
      
              if (newCommand != null)
                  newCommand.CanExecuteChanged += HandleCanExecuteChanged;
      
              HandleCanExecuteChanged(newCommand, EventArgs.Empty);
          }
      
          private void HandleCanExecuteChanged(object sender, EventArgs args)
          {
              if (DoubleClickCommand != null)
                  IsEnabled = DoubleClickCommand.CanExecute(DoubleClickCommandParameter);
          }      
      }
      

      然后,当您创建 ListBoxItems 时,您将绑定到新的命令属性。

      <local:CommandListBoxItem DoubleClickCommand="{Binding ItemDoubleClickedCommand}" />
      

      【讨论】:

        【解决方案3】:

        【讨论】:

        • 这个例子似乎有点广泛,我回家再试一试,我会给出反馈。感谢您的建议!
        猜你喜欢
        • 1970-01-01
        • 2012-06-19
        • 2019-05-04
        • 1970-01-01
        • 2010-12-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多