Qwe*_*tie 5 wpf events datatemplate mvvm
我试图第一次使用MVVM模式.所以我ItemsControl填充了我的viewmodel对象,使用DataTemplate's 显示; 对象是"节点"和"边缘",DataTemplate用Thumb和Polyline对象表示,我希望能够检测到点击和拖动ItemsControl,以便移动节点和边缘.
两个问题:
Polyline's和Thumb?(我可以将一个Thumb.DragDelta处理程序附加到ItemsControl并e.OriginalSource指向Thumb,但是如何获取相应的viewmodel对象?)ItemsControl到检测鼠标单击和拖动空白区域?(答案如下)注意:我知道如果它直接处理View的事件,它可能不被认为是正确的ViewModel.但重要的是,我需要处理鼠标事件,我不知道如何附加它们.
我找到了一种方法来处理DataTemplate中的对象引发的事件.
(1)将事件处理程序附加到ItemsControl
<ItemsControl x:Name="_itemsControl"
Thumb.DragStarted="Node_DragStarted"
Thumb.DragDelta="Node_DragDelta"
Thumb.DragCompleted="Node_DragCompleted"
MouseDoubleClick="OnMouseDoubleClick"
.../>
Run Code Online (Sandbox Code Playgroud)
(2)找出事件适用的项目,将OriginalSource视为FrameworkElement,并获取其DataContext:
void Node_DragStarted(object sender, DragStartedEventArgs e)
{
var os = (FrameworkElement)e.OriginalSource;
var vm = os.DataContext as ItemViewModel;
if (vm != null)
// do something with the item ViewModel
}
Run Code Online (Sandbox Code Playgroud)
我找到了第二个问题的答案。我需要一个支持滚动的 ItemsControl,并且需要将项目放在 Grid 而不是默认的 StackPanel 上。为了满足这两个要求,我使用了 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"/>
Run Code Online (Sandbox Code Playgroud)
为了获取具有有意义的鼠标坐标(即可滚动空间中的坐标)的鼠标事件,有必要使用奇怪的咒语来获取对网格的引用:
Grid grid = (Grid)_itemsControl.Template.FindName("Panel", _itemsControl);
Run Code Online (Sandbox Code Playgroud)
然后将事件处理程序附加到网格,并在鼠标事件处理程序内,使用以下命令获取网格的鼠标坐标
Point p = e.GetPosition((IInputElement)sender);
Run Code Online (Sandbox Code Playgroud)
为了在整个表面上获取鼠标事件,控件(实际上是网格)必须有背景,因此我在上面设置了Background =“LightYellow”,它通过ControlTemplate中的绑定传播到网格。