using System; using System.Collections; using System.Windows.Media; using System.Windows.Documents; using System.Windows; namespace Microsoft.Windows.Controls.Core { /// /// An adorner that can display one and only one UIElement. /// That element can be a panel, which contains multiple other elements. /// The element is added to the adorner's visual and logical trees, enabling it to /// particpate in dependency property value inheritance, amongst other things. /// internal class UIElementAdorner : Adorner where TElement : UIElement { #region Fields TElement _child = null; double _offsetLeft = 0; double _offsetTop = 0; #endregion // Fields #region Constructor /// /// Constructor. /// /// The element to which the adorner will be bound. public UIElementAdorner(UIElement adornedElement) : base(adornedElement) { } #endregion // Constructor #region Public Interface #region Child /// /// Gets/sets the child element hosted in the adorner. /// public TElement Child { get { return _child; } set { if (value == _child) return; if (_child != null) { base.RemoveLogicalChild(_child); base.RemoveVisualChild(_child); } _child = value; if (_child != null) { base.AddLogicalChild(_child); base.AddVisualChild(_child); } } } #endregion // Child #region GetDesiredTransform /// /// Override. /// /// /// public override GeneralTransform GetDesiredTransform(GeneralTransform transform) { GeneralTransformGroup result = new GeneralTransformGroup(); result.Children.Add(base.GetDesiredTransform(transform)); result.Children.Add(new TranslateTransform(_offsetLeft, _offsetTop)); return result; } #endregion // GetDesiredTransform #region OffsetLeft /// /// Gets/sets the horizontal offset of the adorner. /// public double OffsetLeft { get { return _offsetLeft; } set { _offsetLeft = value; UpdateLocation(); } } #endregion // OffsetLeft #region SetOffsets /// /// Updates the location of the adorner in one atomic operation. /// public void SetOffsets(double left, double top) { _offsetLeft = left; _offsetTop = top; this.UpdateLocation(); } #endregion // SetOffsets #region OffsetTop /// /// Gets/sets the vertical offset of the adorner. /// public double OffsetTop { get { return _offsetTop; } set { _offsetTop = value; UpdateLocation(); } } #endregion // OffsetTop #endregion // Public Interface #region Protected Overrides /// /// Override. /// /// /// protected override Size MeasureOverride(Size constraint) { if (_child == null) return base.MeasureOverride(constraint); _child.Measure(constraint); return _child.DesiredSize; } /// /// Override. /// /// /// protected override Size ArrangeOverride(Size finalSize) { if (_child == null) return base.ArrangeOverride(finalSize); _child.Arrange(new Rect(finalSize)); return finalSize; } /// /// Override. /// protected override IEnumerator LogicalChildren { get { ArrayList list = new ArrayList(); if (_child != null) list.Add(_child); return list.GetEnumerator(); } } /// /// Override. /// /// /// protected override Visual GetVisualChild(int index) { return _child; } /// /// Override. /// protected override int VisualChildrenCount { get { return _child == null ? 0 : 1; } } #endregion // Protected Overrides #region Private Helpers void UpdateLocation() { AdornerLayer adornerLayer = base.Parent as AdornerLayer; if (adornerLayer != null) adornerLayer.Update(base.AdornedElement); } #endregion // Private Helpers } }