Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF: How to attach mouse events to a viewmodel?

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 and Thumb's to be handled by the little viewmodels? (I could attach a Thumb.DragDelta handler to the ItemsControl and e.OriginalSource points to the Thumb, 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.

like image 499
Qwertie Avatar asked May 15 '09 18:05

Qwertie


2 Answers

I found a way to handle events raised by objects in the DataTemplate.

(1) attach event handlers to the ItemsControl

<ItemsControl x:Name="_itemsControl" 
              Thumb.DragStarted="Node_DragStarted"
              Thumb.DragDelta="Node_DragDelta"
              Thumb.DragCompleted="Node_DragCompleted"
              MouseDoubleClick="OnMouseDoubleClick"
              .../>

(2) to find out which item the event applies to, treat the OriginalSource as a FrameworkElement, and get its 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
}
like image 162
Qwertie Avatar answered Oct 05 '22 12:10

Qwertie


The ViewModel should be disconnected from the GUI, so it doesn't know anything about controls or mouseclicks.

Two options:

  • Call a command in the the ViewModel, as suggested by Thomas
  • Bind the position of the thumb to a property in the ViewModel, then when the control moves around WPF will update the position values in the ViewModel.
like image 31
Cameron MacFarland Avatar answered Oct 05 '22 11:10

Cameron MacFarland