ToolTip on Adorner doesn't show up

2019-06-13 20:17发布

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?

1条回答
Rolldiameter
2楼-- · 2019-06-13 20:37

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.

查看更多
登录 后发表回答