/// <summary> /// Handle thumb drag /// </summary> private void MoveThumbDragDelta(object sender, DragDeltaEventArgs e) { // dragging content - question or bubble DependencyObject content; // find dragging content - layout different for question and bubbles Adorner adorner = VisualTreeHelper.GetParent(this) as Adorner; if (adorner != null) { content = adorner.AdornedElement; } else { var grid = VisualTreeHelper.GetParent(this); content = VisualTreeHelper.GetParent(grid); } // presenter that holds omr item ContentPresenter presenter = (ContentPresenter)VisualTreeHelper.GetParent(content); // parent canvas CustomCanvas canvas = (CustomCanvas)VisualTreeHelper.GetParent(presenter); // get all selected elements List <ContentPresenter> presenters = ControlHelper.GetSelectedChildPresenters(canvas); double deltaHorizontal = e.HorizontalChange; double deltaVertical = e.VerticalChange; // check out of bounds for each item for (int i = 0; i < presenters.Count; i++) { if (Canvas.GetLeft(presenters[i]) + deltaHorizontal > canvas.ActualWidth - presenters[i].ActualWidth - BorderThreshold || Canvas.GetLeft(presenters[i]) + deltaHorizontal < BorderThreshold) { deltaHorizontal = 0; } if (Canvas.GetTop(presenters[i]) + deltaVertical > canvas.ActualHeight - presenters[i].ActualHeight - BorderThreshold || Canvas.GetTop(presenters[i]) + deltaVertical < BorderThreshold) { deltaVertical = 0; } } // apply change for each item for (int i = 0; i < presenters.Count; i++) { Canvas.SetLeft(presenters[i], Canvas.GetLeft(presenters[i]) + deltaHorizontal); Canvas.SetTop(presenters[i], Canvas.GetTop(presenters[i]) + deltaVertical); } // canvas.InvalidateMeasure(); e.Handled = true; }
/// <summary> /// Occurs as the mouse changes position when a Thumb control has logical focus and mouse capture /// </summary> /// <param name="sender">The sender</param> /// <param name="e">The event args</param> private void ResizeDragDelta(object sender, DragDeltaEventArgs e) { // get to resized element Grid thumbsGrid = (Grid)VisualTreeHelper.GetParent(this); ResizeThumb parentThumb = (ResizeThumb)VisualTreeHelper.GetParent(thumbsGrid); Adorner adorner = (Adorner)VisualTreeHelper.GetParent(parentThumb); // presenter that holds dragged item ContentPresenter presenter = (ContentPresenter)VisualTreeHelper.GetParent(adorner.AdornedElement); // parent canvas CustomCanvas canvas = (CustomCanvas)VisualTreeHelper.GetParent(presenter); // prepare items for resize depending on item level (question or bubble) List <ContentPresenter> presenters; if (canvas.Name.Equals(Properties.Resources.RootCanvasName)) { // here we resize questions (e.g. choicebox), so take selected items presenters = ControlHelper.GetSelectedChildPresenters(canvas); } else { // here we resize bubbles, so get neighbor bubbles inside question (always resize bubbles equally) presenters = ControlHelper.GetChildPresenters(canvas); } double minLeft, minTop, minDeltaHorizontal, minDeltaVertical; double maxDeltaVertical, maxDeltaHorizontal; double maxHorizontalDeltaToChild = double.MaxValue; double maxVerticalDeltaToChild = double.MaxValue; this.CalculateLimits(canvas, presenters, out minLeft, out minTop, out minDeltaHorizontal, out minDeltaVertical, out maxDeltaHorizontal, out maxDeltaVertical); minDeltaVertical = Math.Min(minDeltaVertical, maxVerticalDeltaToChild); minDeltaHorizontal = Math.Min(minDeltaHorizontal, maxHorizontalDeltaToChild); foreach (ContentPresenter element in presenters) { double newHeight = element.ActualHeight; double newWidth = element.ActualWidth; double newTop = Canvas.GetTop(element); double newLeft = Canvas.GetLeft(element); double scale, dragDeltaVertical; switch (this.VerticalAlignment) { case VerticalAlignment.Bottom: dragDeltaVertical = Math.Max(Math.Min(-e.VerticalChange, minDeltaVertical), -maxDeltaVertical); newHeight = element.ActualHeight - dragDeltaVertical; break; case VerticalAlignment.Top: dragDeltaVertical = Math.Min(Math.Max(-minTop, e.VerticalChange), minDeltaVertical); scale = (element.ActualHeight - dragDeltaVertical) / element.ActualHeight; newTop = newTop - element.Height * (scale - 1); newHeight = element.ActualHeight - dragDeltaVertical; break; } double dragDeltaHorizontal; switch (this.HorizontalAlignment) { case HorizontalAlignment.Left: dragDeltaHorizontal = Math.Min(Math.Max(-minLeft, e.HorizontalChange), minDeltaHorizontal); scale = (element.ActualWidth - dragDeltaHorizontal) / element.ActualWidth; newLeft = Canvas.GetLeft(element) - element.Width * (scale - 1); newWidth = element.ActualWidth * scale; break; case HorizontalAlignment.Right: dragDeltaHorizontal = Math.Max(Math.Min(-e.HorizontalChange, minDeltaHorizontal), -maxDeltaHorizontal); newWidth = element.ActualWidth - dragDeltaHorizontal; break; } var childs = this.GetChildElements(element); if (childs == null) { element.Width = newWidth; element.Height = newHeight; Canvas.SetTop(element, newTop); Canvas.SetLeft(element, newLeft); } else { double scaleH = newHeight / element.ActualHeight; double scaleW = newWidth / element.ActualWidth; if (this.CanTransformChildsRecursive(childs, scaleH, scaleW)) { this.TransformChildsRecursive(childs, scaleH, scaleW); element.Width = newWidth; element.Height = newHeight; Canvas.SetTop(element, newTop); Canvas.SetLeft(element, newLeft); } } } e.Handled = true; }