我的Canvas
包含Rectangle
。在该画布上,我将mousedown事件绑定到ViewModel上的命令。在该命令中,我正在通过MouseEventArgs
,但Target元素是Canvas
或Rectangle
。我在哪里可以找到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解决方案。这需要工作但是画布中的元素很复杂。例如,它可能包含另一个画布。
答案 0 :(得分:1)
视图模型不应该首先引用一个UI元素,例如Canvas
或Rectangle
。这有效地打破了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
。它将由纯粹的命中测试确定。