Display an Adorner over a WebBrowser control
Asked Answered
F

4

7

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.

Finlay answered 17/2, 2010 at 19:4 Comment(0)
W
2

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.

Wolpert answered 26/10, 2010 at 20:42 Comment(0)
D
5

I don't think that will work with an Adroner, but you can float content over a WebBroswer control using a transparent Popup control. More details and a code sample can be found here.

Daynadays answered 17/2, 2010 at 19:31 Comment(1)
Yeah.... I'd seen that elsewhere. It looks like this is because a popup is an hwnd as well, so that's handy. The only thing here is that is cuts off adorners meant to decorate other objects around it. I'll update my answer to reflect this. Very good suggestion though... I might see about wrapping my adorner in an hwnd.Finlay
L
3

Here's my blog post introducing a library I wrote for layering a WPF adorner over any hwnd. A simple web browser demo looks like this: snapshot

Laxity answered 24/12, 2014 at 10:53 Comment(0)
W
2

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.

Wolpert answered 26/10, 2010 at 20:42 Comment(0)
I
1

Try use another transparent TOP LEVEL overlay window. Only supported on Windows 2000 or higher of course, Win9x does not have layered windows.

Interlocutory answered 27/2, 2010 at 18:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.