WPF Adorners Part 2 – Placing any control on the adorner layer

This is part 2 of a series you may want to read part 1 first.

In the previous post in this series we created a trivial adorner and placed it over a button – in this post we will look at placing something more complex inside an adorner.

We’ve already seen Adroner is a FrameworkElement and we know FrameworkElement can contain other visuals inside it – so let’s just write an adorner that contains a control:

using System;
using System.Windows.Documents;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Media;

namespace AdornerDemo
{
    class ControlAdorner : Adorner
    {
        private Control _child;

        public ControlAdorner(UIElement adornedElement)
            : base(adornedElement)
        {
        }

        protected override int VisualChildrenCount
        {
            get
            {
                return 1;
            }
        }

        protected override Visual GetVisualChild(int index)
        {
            if (index != 0) throw new ArgumentOutOfRangeException();
            return _child;
        }

        public Control Child
        {
            get { return _child; }
            set
            {
                if (_child != null)
                {
                    RemoveVisualChild(_child);
                }
                _child = value;
                if (_child != null)
                {
                    AddVisualChild(_child);
                }
            }
        }

        protected override Size MeasureOverride(Size constraint)
        {
            _child.Measure(constraint);
            return _child.DesiredSize;
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            _child.Arrange(new Rect(new Point(0, 0), finalSize));
            return new Size(_child.ActualWidth, _child.ActualHeight);
        }
    }
}

This is a completely standard implementation of a FramwrorkElement that contains a child control.

You may be asking yourself why a control and not a Visual or a UIElement, this is because the way we will use this adorner in a future post.

Now let’s use our new adorner by placing a button over the button from our previous program:

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    Button inAdorner = new Button()
    {
        HorizontalAlignment = HorizontalAlignment.Right,
        Content = "X",
    };
    ControlAdorner adorner = new ControlAdorner(Btn)
    {
        Child = inAdorner,
    };
    AdornerLayer.GetAdornerLayer(Btn).Add(adorner);
}

Yes, this is a silly example, but think what you can do by placing a UserControl over an existing control.

In the next post we will look into the potential of the adorner layer.

posted @ Monday, June 28, 2010 11:48 AM

Comments on this entry:

# re: WPF Adorners Part 2 – Placing any control on the adorner layer

Left by Vasiliy at 1/19/2011 6:21 PM

Thanks very much for posting these, Nir, they helped me out quite a bit!

# re: WPF Adorners Part 2 – Placing any control on the adorner layer

Left by Brad at 1/11/2012 12:42 AM

I followed your example to put a TextBox over a TextBlock in order to create an editable TextBlock. Works like a dream! Thanks a lot. Best wishes.

# re: WPF Adorners Part 2 – Placing any control on the adorner layer

Left by terorero at 5/17/2012 12:33 PM

THIS IS GONNA BE AWESOME

# re: WPF Adorners Part 2 – Placing any control on the adorner layer

Left by badik at 8/5/2013 8:12 AM

Simple & clean post, helped me, thank u ;-)

# re: WPF Adorners Part 2 – Placing any control on the adorner layer

Left by Sam at 5/4/2014 5:17 AM

This was really helpful. You rock !

Your comment:



 (will not be displayed)


 
 
Please add 2 and 8 and type the answer here: