如何向控件的事件添加新命令

时间:2010-04-21 10:59:19

标签: wpf mvvm

感谢您查看此问题。

我按照Josh Smith的MVVM模式示例构建了一个应用程序(VB / WPF):Click here to view

我的视图具有触发命令的控件,例如按钮单击,这些控件绑定到ViewModel中的属性。

我的ViewModel公开了ICommand类型的属性,它调用了适当的方法。

这一直运作良好,直到现在!我现在想要使用Thumb控件允许用户在Canvas中移动对象。我不相信Thumb具有“开箱即用”的命令功能。移动时,Thumb会引发“DragDelta”事件。所以我的问题如下:

如何扩展Control对事件发出命令的能力?

我希望发出一个新命令,让我们说'onDragDelta',这样我就可以将它绑定到我的ViewModel中的属性,就像我的Buttons一样。

非常感谢

2 个答案:

答案 0 :(得分:3)

您想要的是基于FrameworkElement的RoutedEvent在ViewModel中触发ICommand。不幸的是,WPF不支持这种“开箱即用”。一些可能性:

1)使用Expression Blend 3,可以使用Microsoft.Expression.Interactivity.dll。有关如何执行此操作的示例,请参阅WPF : Blend 3 Interactions / Behaviours

2)您可以在代码隐藏中使用事件处理程序,它直接调用相应的ViewModel命令。例如:

private void FrameworkElement_DragDelta(object sender, EventArgs e)
{
    this.MyViewModel.OnDragDelta(sender, e);
}

3)作为Cinch框架的一部分,有一个attached command behaviour。这样,您就不必更改代码隐藏。例如:

Cinch:SingleEventCommand.RoutedEventName="DragDelta"
Cinch:SingleEventCommand.TheCommandToRun="{Binding Path=DragDeltaCommand}"

请注意,这会调用ICommand并将对象(实际上是SCommandArgs)作为命令参数传递。要在命令处理程序中获取实际的路由事件参数,请执行以下操作:

var sargs = args as SCommandArgs;
if (sargs == null)
{
    return;
}

var routedEventArgs = sargs.EventArgs as RoutedEventArgs; // Or whatever arguments you actually expect
if (routedEventArgs == null)
{
    return;
}

// Do something here with the event arguments

编辑:另请查看Binding Commands to Events?

答案 1 :(得分:0)

我宁愿数据将Thumb的当前位置绑定到ViewModel中的属性,而不是使用ICommand。现在,如果位置发生了变化,您可以在ViewModel中执行一些方法,并将差值作为参数。

我不知道这是否符合您的需求,但这是我的第一个想法。