Wpf鼠标事件在画布上设置,但是以子对象为目标

时间:2017-02-24 10:44:24

标签: wpf events canvas

我的Canvas包含Rectangle。在该画布上,我将mousedown事件绑定到ViewModel上的命令。在该命令中,我正在通过MouseEventArgs,但Target元素是CanvasRectangle。我在哪里可以找到MouseEventArgs Canvas这个事件被解雇了?

我的代码或多或少:

<Canvas Background="White">
    <i:EventTrigger EventName="MouseLeftButtonDown">
        <local:InteractiveCommand Command="{Binding CmdMouseLeftButtonDown}"/>
    </i:EventTrigger>
    <Rectangle Width="50" Height="50" />
</Canvas>

在ViewModel中:

ICommand CmdMouseLeftButtonDown => new DelegateCommand<MouseEventArgs>(e => 
{
    e.??? // <= Where do I find the Canvas here, whether I click on the Rectangle or Canvas?
}

请不要使用像e.MouseDevice.Target.Parent这样的hackish解决方案。这需要工作但是画布中的元素很复杂。例如,它可能包含另一个画布。

2 个答案:

答案 0 :(得分:1)

视图模型不应该首先引用一个UI元素,例如CanvasRectangle。这有效地打破了MVVM模式,这就是为什么将sender参数传递给命令是没有意义的。

你也可以摆脱EventTrigger并从视图的代码隐藏中以编程方式调用命令:

<Canvas Background="White" MouseLeftButtonDown="Canvas_MouseLeftButtonDown">
    <Rectangle Width="50" Height="50" Fill="Red" />
</Canvas>
private void Canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    var yourViewModel vm = DataContext as YourClass;
    vm.CmdMouseLeftButtonDown.Execute(sender as Canvas); //<-- pass the Canvas as a command argument or create a new command argument type that holds a reference to the Canvas
}

就MVVM模式而言,这肯定不比您当前的方法更差。您仍在从同一视图调用相同的命令,MVVM不是要删除代码。这是关于分离关注点。

答案 1 :(得分:0)

col1 col2List col3List 1 2,3,4,5 3,4,6 在任何情况下都会引用MouseEventArgs.Source,但Canvas会在MouseEventArgs.OriginalSource点击其区域时引用Rectange。它将由纯粹的命中测试确定。