I see a strange behaviour dragging in Line shape over a Canvas that I cannot explain. The Line shape is in a Thumb DataTemplate like so:
It turns out that the Line shape behaves somewhat different from the Ellipse shape when added to a Thumb. The Thumb fires in its DragDelta
event the total displacment of the mouse w.r.t. the position where the left button was pressed when the dragging started.
For an ellipse this is ok, because internally, the EllipseGeometry
of the Ellipse shape is stretched to fill Rectangle that is positioned on the Canvas with Canvas.Left, Canvas.Top, Width and Height. Apparantly the total displacement is the correct value to animate the dragging of the ellipse on the canvas.
For a Line the correct value to animate the dragging of the ellipse on the canvas is the difference of the displacement between two consecutive DragDelta
events. A Line is drawn on the basis of X1, X2, Y1, Y2 properties of an internal LineGeometry
. The Rectangle of its GeometryBounds
are ignored (although the line is clipped beyond this border). The Line's Canvas.Left=Canvas.Top can then be set to 0 and Width and Height equal to the ActualHeight and ActualWidth of the Canvas.
One could also create an own Ellipse shape with a Center and Radius property. Such a shape then would behave like the Line shape.
What I did is create a ThumbShape as a base class, copying code from Thumb.cs of MS. Therfore I also had to copy the corresponding EventArgs classes and EventHandler delegates. I added to the DragDelta
eventarguments a relative mouse change so that I can choose whether to use the relative offset or the total offset of the dragging.
I had the same problem and after this answer "For a Line the correct value to animate the dragging of the ellipse on the canvas is the difference of the displacement between two consecutive DragDelta events." I developed this solution, worked for me, hope this helps someone
public class Connector : Thumb
{
private double _oldX = 0;
private double _oldY = 0;
public Connector()
{
DragDelta += Connector_DragDelta;
DragCompleted += Connector_DragCompleted;
}
private void Connector_DragCompleted(object sender, DragCompletedEventArgs e)
{
_oldX = 0;
_oldY = 0;
}
private void Connector_DragDelta(object sender, DragDeltaEventArgs e)
{
Thumb thumb = e.Source as Thumb;
DiagramConnectorViewModel viewModel = (DiagramConnectorViewModel)thumb.DataContext;
double leftOffSet = _oldX - e.HorizontalChange;
_oldX = e.HorizontalChange;
viewModel.X1 -= leftOffSet;
viewModel.X2 -= leftOffSet;
double topOffSet = _oldY - e.VerticalChange;
_oldY = e.VerticalChange;
viewModel.Y1 -= topOffSet;
viewModel.Y2 -= topOffSet;
}