public static UIAdorner InCanvas(FrameworkElement adornee, FrameworkElement content, Point initialPosition) { var canvas = new WpfCanvas {}; var adorner = new UIAdorner(adornee, canvas); canvas.Children.Add(content); WpfCanvas.SetTop(content, initialPosition.Y); WpfCanvas.SetLeft(content, initialPosition.X); return adorner; }
private void withDragMarquee(Action<Rect> doWithRect) { var canvas = new System.Windows.Controls.Canvas(); var adornerLayer = AdornerLayer.GetAdornerLayer(this); var adorners = adornerLayer.GetAdorners(this); if (adorners != null) foreach (var a in adorners) if (a is UIAdorner && ((UIAdorner)a).contentType == typeof(System.Windows.Controls.Canvas)) return; var adorner = new UIAdorner(this, canvas); var marquee = new Rectangle { Fill = Brushes.Purple, Opacity = 0.4 }; canvas.Background = new SolidColorBrush { Color = Colors.Wheat, Opacity = 0.1 }; canvas.Children.Add(marquee); bool mouseDown = false; Point origin = new Point(-1, -1); Rect finalRect = new Rect(); canvas.MouseDown += (sender, e) => { var pos = e.GetPosition(this); var visPos = e.GetPosition(canvas); System.Windows.Controls.Canvas.SetLeft(marquee, visPos.X); System.Windows.Controls.Canvas.SetTop(marquee, visPos.Y); origin = pos; mouseDown = true; }; canvas.MouseUp += (sender, e) => { if (origin.X == -1 || origin.Y == -1) return; var pos = e.GetPosition(this); finalRect.X = (pos.X < origin.X) ? pos.X : origin.X; finalRect.Y = (pos.Y < origin.Y) ? pos.Y : origin.Y; finalRect.Height = Math.Abs(pos.Y - origin.Y); finalRect.Width = Math.Abs(pos.X - origin.X); mouseDown = false; if (!isPointNear(marquee.PointToScreen(finalRect.TopLeft), marquee.PointToScreen(finalRect.BottomRight), 10)) doWithRect(finalRect); adornerLayer.Remove(adorner); }; canvas.MouseMove += (sender, e) => { if (!mouseDown || origin.X == -1 || origin.Y == -1) return; var pos = e.GetPosition(canvas); System.Windows.Controls.Canvas.SetLeft(marquee, Math.Min(origin.X, pos.X)); System.Windows.Controls.Canvas.SetTop(marquee, Math.Min(origin.Y, pos.Y)); marquee.Width = Math.Max(origin.X, pos.X) - Math.Min(origin.X, pos.X); marquee.Height = Math.Max(origin.Y, pos.Y) - Math.Min(origin.Y, pos.Y); }; canvas.MouseLeave += (_sender, _args) => { adornerLayer.Remove(adorner); Commands.EndGrabZoom.ExecuteAsync(null); }; adornerLayer.Add(adorner); }