wpfcomwebbrowser-controlhwndadorner

Display an Adorner over a WebBrowser control


I'm using the System.Windows.Controls.WebBrowser for various things in my app and I've noticed that adorners are cut off when they are supposed to appear over a WebBrowser. I realize that the WebBrowser control is really a wrapper around a COM component and probably renders differently, but I wondered if anyone figured out how to solve this.

This is the problem I'm seeing. Here I have just a sample adorner that is supposed to draw a big red circle in the top corner of something (as a sample).

When I adorn the WebBrowser with this, I get this result:

I expect to see the full circle.

Here's the code for this worthless adorner, in case that is helpful:

public class SillyAdorner : Adorner
{
    public SillyAdorner(UIElement element) : base(element)
    {

    }
    protected override void OnRender(DrawingContext drawingContext)
    {
        drawingContext.DrawEllipse(new SolidColorBrush(Colors.Red), new Pen(), new Point(7, 7), 30, 30);
        base.OnRender(drawingContext);
    }
}

And here is how I apply it to the browser in the OnRender method of the host control:

    protected override void OnRender(DrawingContext drawingContext)
    {
        base.OnRender(drawingContext);            
        var layer = AdornerLayer.GetAdornerLayer(browser);
        layer.Add(new SillyAdorner(browser));
    }

Anyone have any hacks or workarounds for this?

Edit: I'm using .NET 4.0, if that makes a difference.

Edit #2: WebBrowser appears to inherit from HwndHost, which I've seen another question or two regarding adorners and hwndsources, but I'm not seeing anything that looks like I could implement it for the WebControl, but hopefully this is useful information for someone.


Solution

  • This is caused by airspace issues. Since a WebBrowser is a native, non-WPF control, there is no way to directly render adorners (or other WPF content) on top of it.

    In order to do this, you need to use a separate window of some sort, and put the content into that separate window. This typically means using a transparent WPF window layered over the top of your main window. Unfortunately, this will not be as integrated of a solution as a true native WPF control would provide.