WPF:如何将鼠标事件附加到viewmodel? [英] WPF: How to attach mouse events to a viewmodel?
问题描述
ItemsControl
填充我的viewmodel对象,使用 DataTemplate
对象是在 DataTemplate
中以 Thumb
和表示的节点和 Polyline
对象,我想能够检测 ItemsControl
上的点击和拖动,以移动节点和边缘。 两个问题:
- 如何将鼠标事件处理程序附加到
Polyline
和Thumb
是由小型模式处理? (我可以将Thumb.DragDelta
处理程序附加到ItemsControl
和e.OriginalSource
指向
Thumb
,但如何获取相应的viewmodel对象?) - 如何附加鼠标事件处理程序到
ItemsControl
以检测鼠标点击和拖动空白? (答案如下)
注意:我知道如果直接处理View的事件,它可能不被认为是适当的ViewModel。但是重要的是,我需要处理鼠标事件,我不知道如何附加它们。
我想到了第二个问题的答案。我需要一个支持滚动的ItemsControl,我需要在Grid上使用这些项,而不是默认的StackPanel。为了满足这两个要求,我使用了一个ControlTemplate:
<! - 在资源...-->
< ControlTemplate x:Key =GraphTemplateTargetType =ItemsControl>
< ScrollViewer Name =ScrollViewer
Padding ={TemplateBinding Padding}
HorizontalScrollBarVisibility =Auto>
...
< Grid Name =PanelIsItemsHost =True
Background ={TemplateBinding ItemsControl.Background}/>
...
< / ScrollViewer>
< / ControlTemplate>
<! - 以后...-->
< ItemsControl x:Name =_ itemsControl
ItemsSource ={Binding Items}
Template ={StaticResource GraphTemplate}
Background =LightYellow/>
为了获得有意义的鼠标坐标(即可滚动空间的坐标)的鼠标事件,使用奇怪的咒语来获取对网格的引用:
Grid grid =(Grid)_itemsControl.Template.FindName(Panel ,_itemsControl);
然后将事件处理程序附加到网格中,并在鼠标事件处理程序内部获取鼠标坐标w.r.t.网格使用
点p = e.GetPosition((IInputElement)sender);
为了在整个表面上获取鼠标事件,控件(实际上是网格)必须有背景,所以我设置Background =LightYellow,它通过ControlTemplate中的绑定传播到网格。
I am trying to use the MVVM pattern for the first time. So I have an ItemsControl
filled with my viewmodel objects, displayed using DataTemplate
's; the objects are "nodes" and "edges" represented in DataTemplate
's with Thumb
and Polyline
objects and I want to be able to detect clicks and drags on the ItemsControl
in order to move the nodes and edges.
Two questions:
- How do I attach mouse event handlers to the
Polyline
's andThumb
's to be handled by the little viewmodels? (I could attach aThumb.DragDelta
handler to theItemsControl
ande.OriginalSource
points to theThumb
, but how do I get the corresponding viewmodel object?) - How do I attach mouse event handlers to the
ItemsControl
to detect mouse clicks and drags on blank space? (answer is below)
Note: I know it might not be considered a proper ViewModel if it's directly handling events of the View. But the important point is, I need to handle mouse events and I am not sure how to attach them.
I figured out the answer to the second question. I needed an ItemsControl that supported scrolling, and I needed to have the items on a Grid rather than the default StackPanel. To fulfill both requirements, I used a ControlTemplate:
<!--In the resources...-->
<ControlTemplate x:Key="GraphTemplate" TargetType="ItemsControl">
<ScrollViewer Name="ScrollViewer"
Padding="{TemplateBinding Padding}"
HorizontalScrollBarVisibility="Auto">
...
<Grid Name="Panel" IsItemsHost="True"
Background="{TemplateBinding ItemsControl.Background}"/>
...
</ScrollViewer>
</ControlTemplate>
<!--Later...-->
<ItemsControl x:Name="_itemsControl"
ItemsSource="{Binding Items}"
Template="{StaticResource GraphTemplate}"
Background="LightYellow"/>
In order to get mouse events with meaningful mouse coordinates (i.e. coordinates in scrollable space), it was necessary to obtain a reference to the grid using a strange incantation:
Grid grid = (Grid)_itemsControl.Template.FindName("Panel", _itemsControl);
Then you attach event handlers to the grid, and inside the mouse event handlers, get the mouse coordinates w.r.t. the grid using
Point p = e.GetPosition((IInputElement)sender);
In order to get mouse events on the entire surface, the control (actually the grid) must have a background, so I set Background="LightYellow" above, which propagates to the grid via a binding in the ControlTemplate.
这篇关于WPF:如何将鼠标事件附加到viewmodel?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!