将事件args和发送者传递给RelayCommand

inc*_*ito 10 .net relaycommand mvvm-light

使用RelayCommand时如何获得事件发送者?

Hen*_*und 19

这是那些痛苦的答案之一,我实际上并没有回答你的问题,而是向你讲述你应该采取哪些不同的做法.所以,抱歉.开始:

如果您发现自己处于需要访问viewmodel中的sender对象的位置,那么您应该做一些与众不同的事情.通过引用视图模型中的Button或ListBox,您可以使该视图模型了解它不应该知道的UI概念.我的建议是在代码隐藏页面中连接到事件,找出你需要知道的关于发送者或什么不是的事情,然后以编程方式执行viewmodel命令.这也打破了MVVM"规则",但恕我直言,这比在视图模型中引用发件人要轻得多.


小智 10

我遇到了类似的问题,但只需要获取EventArgs.很高兴,一旦我在Stack Overflow的另一个帖子中找到答案,这就太荒谬了.

<cmd:EventToCommand Command="{Binding SomeCommand, Mode=OneWay}" PassEventArgsToCommand="True"/>
Run Code Online (Sandbox Code Playgroud)

一旦你了解了那个神奇的"PassEventArgsToCommand"设置,你就是金色的.只需使用一个RelayCommand<type>普通的RelayCommand.

我希望这有帮助.

  • 只想评论一下:PassEventArgsToCommand不是很干净,因为它通过将UI类(EventArgs)引入VM来打破关注点的分离.使用它会使您的VM不易测试.然而,有些情况(例如拖放),其他任何东西都会更脏.这就是我将其添加到EventToCommand中的原因.虽然使用很多照顾! (5认同)
  • 虽然PassEventArgsToCommand可能不干净,但我发现尝试将SkyDrive支持添加到我的WP7应用程序时很有用.登录按钮通过事件参数传递实时会话信息.我可以在代码隐藏中处理事件,将Session属性设置为ViewModel然后调用命令.PassEventArgsToCommand有助于编写易于理解的代码. (2认同)

小智 7

这可以通过将发送方绑定到命令参数来完成.

<command:EventToCommand
              Command="{Binding CommandName}"
              CommandParameter="{Binding RelativeSource=
                                         { RelativeSource FindAncestor, 
                                           AncestorType={x:Type TypeOfSender},
                                           AncestorLevel=1}}" 
              PassEventArgsToCommand="True" >
</command:EventToCommand>
Run Code Online (Sandbox Code Playgroud)

  • 我赞成这一点,因为虽然 Henrik 正确地解释了不应该这样做,但世界并不完美,实现纯 MVVM 有时是不可能的。例如,如果您希望 Textbox 在获得焦点时选择所有文本,则需要 TextBox 本身调用其 SelectAll() 成员。这在 MVVM 中无疑是可行的,但它会创建极其复杂的代码,而在某些情况下,这种解决方案“足够好”。我同意应该尽可能地阻止这种行为,但有时你只需要务实,这样的修复虽然丑陋,但有效。 (2认同)
  • 另一个例子:WPF WebBrowser控件.您可以将命令绑定到Navigated事件,但如果您确实想要对http响应执行某些操作,则需要引用浏览器本身,因为该信息不在eventargs中. (2认同)