Search code examples
c#.netwpfdrawingwindowsformshost

In WPF how can you draw a line over a WindowsFormsHost?


Here is my XAML

<Grid
    Name="grid">
    <TextBlock
        Text="Some Label" />
    <WindowsFormsHost
        Name="winFormsHost">

    </WindowsFormsHost>
</Grid>

On the load of the form I execute the following method

protected void OnLoad(object sender, RoutedEventArgs e)
{
    // Create a line on the fly
    Line line = new Line();

    line.Stroke = Brushes.Red;
    line.StrokeThickness = 17;

    line.X1 = 50;
    line.Y1 = 50;

    line.X2 = 250;
    line.Y2 = 50;

    this.grid.Children.Add(line);

    System.Windows.Forms.TextBox oldSchoolTextbox = new System.Windows.Forms.TextBox();
    oldSchoolTextbox.Text = "A bunch of Random Text will follow.  ";
    oldSchoolTextbox.WordWrap = true;
    oldSchoolTextbox.Width = 300;

    for (int i = 0; i < 250; i++)
    {
        oldSchoolTextbox.Text += "abc ";

        if (i % 10 == 0)
        {
            oldSchoolTextbox.Text += Environment.NewLine;
        }
    }

    this.winFormsHost.Child = oldSchoolTextbox;
}

The line only draws when I comment out the following line.

this.winFormsHost.Child = oldSchoolTextbox;

How do I draw a line over the WindowsFormsHost control?


Solution

  • There is something Microsoft has called "airspace" that prevents this from happening, at least easily. Here is the WPF Interop page describing airspace. [It has a DX focus, but the same thing applies, exactly as stated, to WindowsFormsHost.]

    WindowsFormsHost (when it has a child) creates a separate HWND, which prevents the WPF rendering context from displaying in that rectangle.

    The best option for working around this requires .NET 3.5sp1 (at least to work reliably). You can get around this by creating an entirely separate, 100% transparent background window, and placing it over your windows forms host control. You then draw into that, and it will display correctly.

    It's somewhat hacky feeling, but it works.