1

I have an adorner defined as follows:

    private class ErrorAdorner : Adorner
    {
        private readonly Border _errorBorder;

        public ErrorAdorner(UIElement adornedElement)
            : base(adornedElement)
        {
            _errorBorder = new Border();
            _errorBorder.BorderThickness = new Thickness(2);
            _errorBorder.BorderBrush = Brushes.Red;
            Image img = new Image();
            img.HorizontalAlignment = HorizontalAlignment.Right;
            img.VerticalAlignment = VerticalAlignment.Center;
            img.Stretch = Stretch.None;
            Binding imgBinding = new Binding
            {
                Source = adornedElement,
                Path = new PropertyPath(IconProperty)
            };
            img.SetBinding(Image.SourceProperty, imgBinding);
            Binding ttBinding = new Binding
            {
                Source = adornedElement,
                Path = new PropertyPath(ErrorMessageProperty)
            };
            img.SetBinding(ToolTipProperty, ttBinding);
            _errorBorder.Child = img;
        }

        protected override Size MeasureOverride(Size constraint)
        {
            AdornedElement.Measure(constraint);
            return AdornedElement.RenderSize;
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            _errorBorder.Arrange(new Rect(finalSize));
            return finalSize;
        }

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

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

ErrorMessage and Icon are attached properties declared in an enclosing class (ErrorProvider). The adorner is added to an element when the ErrorMessage property is set to a non-null value.

My problem is that while the adorner is properly rendered, the ToolTip on the image doesn't show up when I move the mouse over it. I know it isn't a binding issue: when I examine the controls with Snoop, I can see that the ToolTip property has the expected value. I suspect the problem is related to hit testing, because I can't receive any mouse related event in the adorner... The IsHitTestVisible property is set to true, so I don't understand why I don't receive the events.

Any idea?

Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758

1 Answers1

3

Ok, this is something that has bitten me before also. When you define your own visual tree, it isn't enough to just return the visual children, you also need to tell WPF that you've added them. At the end of your constructor just add this:

this.AddVisualChild(_errorBorder);
this.AddLogicalChild(_errorBorder);

You should also implement the LogicalChildren property:

protected override System.Collections.IEnumerator LogicalChildren
{
    get 
    { 
        yield return _errorBorder;
    }
}

If you had multiple children, I'd use the UIElementCollection. It will add them to the visual and logical trees, and you can just use it from the LogicalChildren, VisualChildrenCount, and GetVisualChild overrides.

Abe Heidebrecht
  • 30,090
  • 7
  • 62
  • 66
  • The Adorner is already not receiving any mouse event, so I don't think it is swallowing anything. I tried anyway, but it doesn't work... – Thomas Levesque Aug 04 '11 at 14:42
  • Yeah, I realized after posting this that the Adorner doesn't have a background, so probably isn't getting it. Is the element disabled? If so, you can use ToolTipService.ShowOnDisabled="True" to allow it to display. – Abe Heidebrecht Aug 04 '11 at 15:10
  • No, it's not disabled. I also tried to put a background, but it doesn't work either (and anyway it wouldn't be an acceptable solution, since it would hide the adorned element) – Thomas Levesque Aug 04 '11 at 15:16
  • I'm gonna either call myself an idiot or claim a lack of caffeine for my lack of reading comprehension earlier. I was thinking the adorned element had the tooltip, and I didn't realize that the Image in the adorner needed to show it. I have come to my senses, and fixed my answer. – Abe Heidebrecht Aug 04 '11 at 15:34