public void OnInkCanvasPreviewMouseDown(object sender, MouseEventArgs e) { if (e == null) { return; } // Finger if (e.StylusDevice != null && e.StylusDevice.StylusButtons.Count == 1 && !this.fingerSelectionMode) { this.InkCanvas.EditingMode = InkCanvasEditingMode.GestureOnly; return; } // Stylus if (e.StylusDevice != null && e.StylusDevice.StylusButtons.Count == 2) { return; } this.InkCanvas.EditingMode = InkCanvasEditingMode.Select; InkCanvas ic = (InkCanvas)sender; Point pt = e.GetPosition(ic); if (ic.HitTestSelection(pt) == InkCanvasSelectionHitResult.Selection) { this.strokesToMove = ic.GetSelectedStrokes(); this.dragDropInProgress = true; this.initialDragPoint = pt; this.polledMouseCoords = new Point(pt.X, pt.Y); } }
//<Snippet3> void InkCanvas_PreviewMouseDown(object sender, MouseEventArgs e) { InkCanvas ic = (InkCanvas)sender; Point pt = e.GetPosition(ic); // If the user is moving selected strokes, prepare the strokes to be // moved to another InkCanvas. if (ic.HitTestSelection(pt) == InkCanvasSelectionHitResult.Selection) { StrokeCollection selectedStrokes = ic.GetSelectedStrokes(); StrokeCollection strokesToMove = selectedStrokes.Clone(); // Remove the offset of the selected strokes so they // are positioned when the strokes are dropped. Rect inkBounds = strokesToMove.GetBounds(); TranslateStrokes(strokesToMove, -inkBounds.X, -inkBounds.Y); // Perform drag and drop. MemoryStream ms = new MemoryStream(); strokesToMove.Save(ms); DataObject dataObject = new DataObject( StrokeCollection.InkSerializedFormat, ms); DragDropEffects effects = DragDrop.DoDragDrop(ic, dataObject, DragDropEffects.Move); if ((effects & DragDropEffects.Move) == DragDropEffects.Move) { // Remove the selected strokes // from the current InkCanvas. ic.Strokes.Remove(selectedStrokes); } } }
/// <summary> /// OnPreviewMouseDown is called before InkCanvas sees the Down. We use this /// handler to hit test any selection and initiate a drag and drop operation /// if the user clicks on the selection to move it. /// </summary> private void OnPreviewMouseDown(object sender, MouseButtonEventArgs e) { InkCanvas inkCanvas = (InkCanvas)sender; Point downPosition = e.GetPosition(inkCanvas); //see if we hit the selection, and not a grab handle if (inkCanvas.HitTestSelection(downPosition) == InkCanvasSelectionHitResult.Selection) { //clone the selected strokes so we can transform them without affecting the actual selection StrokeCollection selectedStrokes = inkCanvas.GetSelectedStrokes(); List <UIElement> selectedElements = new List <UIElement>(inkCanvas.GetSelectedElements()); DataObject dataObject = new DataObject(); //copy ink to the clipboard if we have any. we do this even if there are no //strokes since clonedStrokes will be used by the Xaml clipboard code below StrokeCollection clonedStrokes = selectedStrokes.Clone(); if (clonedStrokes.Count > 0) { //translate the strokes relative to the down position Matrix translation = new Matrix(); translation.Translate(-downPosition.X, -downPosition.Y); clonedStrokes.Transform(translation, false); //save the strokes to a dataobject to use during the dragdrop operation MemoryStream ms = new MemoryStream(); clonedStrokes.Save(ms); ms.Position = 0; dataObject.SetData(StrokeCollection.InkSerializedFormat, ms); //we don't close the MemoryStream here, we'll do it in OnDrop } //Now we're going to add Xaml to the dragdrop dataobject. We'll create an //InkCanvas and add any selected strokes and elements in the selection to it InkCanvas inkCanvasForDragDrop = new InkCanvas(); foreach (UIElement childElement in selectedElements) { //we can't add elements in the selection to the InkCanvas that //represents selection (since they are already parented to the //inkCanvas that has the selection) so we need to clone them. //To clone each element, we need to convert it to Xaml and back again string childXaml = XamlWriter.Save(childElement); UIElement clonedChildElement = (UIElement)XamlReader.Load(new XmlTextReader(new StringReader(childXaml))); //adjust top and left relative to the down position double childLeft = InkCanvas.GetLeft(clonedChildElement); InkCanvas.SetLeft(clonedChildElement, childLeft - downPosition.X); double childTop = InkCanvas.GetTop(clonedChildElement); InkCanvas.SetTop(clonedChildElement, childTop - downPosition.Y); inkCanvasForDragDrop.Children.Add(clonedChildElement); } //last, add the cloned strokes in case our drop location only supports Xaml //this preserves both the ink and the selected elements inkCanvasForDragDrop.Strokes = clonedStrokes; //now copy the Xaml for the InkCanvas that represents selection to the clipboard string inkCanvasXaml = XamlWriter.Save(inkCanvasForDragDrop); dataObject.SetData(DataFormats.Xaml, inkCanvasXaml); //The call to DragDrop.DoDragDrop will block until the drag and drop operation is completed //once it does, 'effects' will have been updated by OnDragOver getting called //if we're moving the strokes and elements, we'll remove them. If we're copying them //(the CTRL key is pressed) we won't remove them. DragDropEffects effects = DragDrop.DoDragDrop(inkCanvas, dataObject, DragDropEffects.Move | DragDropEffects.Copy); if (effects == DragDropEffects.Move) { inkCanvas.Strokes.Remove(selectedStrokes); foreach (UIElement childElement in selectedElements) { inkCanvas.Children.Remove(childElement); } } } }