// Copyright (C) Josh Smith - January 2007 using System; using System.Collections.Generic; using System.Text; using System.Windows.Documents; using System.Windows; using System.Windows.Media; using System.Windows.Shapes; using System.Windows.Media.Animation; using System.Windows.Controls; namespace WPF.JoshSmith.Adorners { /// /// Renders a visual which can follow the mouse cursor, /// such as during a drag-and-drop operation. /// public class DragAdorner : Adorner { #region Data private Rectangle child = null; private double offsetLeft = 0; private double offsetTop = 0; #endregion // Data #region Constructor /// /// Initializes a new instance of DragVisualAdorner. /// /// The element being adorned. /// The size of the adorner. /// A brush to with which to paint the adorner. public DragAdorner(UIElement adornedElement, Size size, Brush brush) : base(adornedElement) { Rectangle rect = new Rectangle(); rect.Fill = brush; rect.Width = size.Width; rect.Height = size.Height; rect.IsHitTestVisible = false; this.child = rect; } #endregion // Constructor #region Public Interface #region GetDesiredTransform /// /// Override. /// /// /// public override GeneralTransform GetDesiredTransform(GeneralTransform transform) { GeneralTransformGroup result = new GeneralTransformGroup(); result.Children.Add(base.GetDesiredTransform(transform)); result.Children.Add(new TranslateTransform(this.offsetLeft, this.offsetTop)); return result; } #endregion // GetDesiredTransform #region OffsetLeft /// /// Gets/sets the horizontal offset of the adorner. /// public double OffsetLeft { get { return this.offsetLeft; } set { this.offsetLeft = value; UpdateLocation(); } } #endregion // OffsetLeft #region SetOffsets /// /// Updates the location of the adorner in one atomic operation. /// /// /// public void SetOffsets(double left, double top) { this.offsetLeft = left; this.offsetTop = top; this.UpdateLocation(); } #endregion // SetOffsets #region OffsetTop /// /// Gets/sets the vertical offset of the adorner. /// public double OffsetTop { get { return this.offsetTop; } set { this.offsetTop = value; UpdateLocation(); } } #endregion // OffsetTop #endregion // Public Interface #region Protected Overrides /// /// Override. /// /// /// protected override Size MeasureOverride(Size constraint) { this.child.Measure(constraint); return this.child.DesiredSize; } /// /// Override. /// /// /// protected override Size ArrangeOverride(Size finalSize) { this.child.Arrange(new Rect(finalSize)); return finalSize; } /// /// Override. /// /// /// protected override Visual GetVisualChild(int index) { return this.child; } /// /// Override. Always returns 1. /// protected override int VisualChildrenCount { get { return 1; } } #endregion // Protected Overrides #region Private Helpers private void UpdateLocation() { AdornerLayer adornerLayer = this.Parent as AdornerLayer; if (adornerLayer != null) adornerLayer.Update(this.AdornedElement); } #endregion // Private Helpers } }