Force ElementHost to redraw

134 Views Asked by At

We have a software that uses Windows Forms's built-in designer (IDesignerHost et al), and custom user controls you can place on the surface.

I'm moving portions of those controls to WPF, using ElementHost. When loading those controls and adding them programmatically, that works, fine. However, when the user interactively adds a new control, its ElementHost portion (in this example, the label at the top) is rendered entirely in black.

Until, that is, I move it around on the design surface.

enter image description here

So clearly, something can be done to force the ElementHost to draw its contents correctly. I'm just not entirely sure what.

There's a number of posts (e.g., ElementHost Layout Problems, ElementHost - Black Background when calling Show method, Black background before loading a wpf controll when using ElementHost), but all of them sound like hacks that don't solve the actual underlying problem.

(edit)

Here's the existing IDesignerHost.CreateComponent implementation:

    <System.Diagnostics.DebuggerStepThrough()>
    Public Function CreateComponent(componentClass As Type, name As String) As IComponent Implements IDesignerHost.CreateComponent
        Dim Component As IComponent = Nothing

        ' Create instance
        Component = CType(Activator.CreateInstance(componentClass), IComponent)

        ' Add to design container
        Add(Component, name)

        Return Component
    End Function

Amending it with a Refresh() like so doesn't help:

[System.Diagnostics.DebuggerStepThrough]
public IComponent CreateComponent(Type componentClass, string name)
{
    IComponent Component = null;

    Component = (IComponent)Activator.CreateInstance(componentClass);

    // Add to design container
    Add(Component, name);

    if (Component is UserControl newUC)
    {
        newUC.Refresh();
    }

    return Component;
}

Toggling Visible does seem to fix the issue:

[System.Diagnostics.DebuggerStepThrough]
public IComponent CreateComponent(Type componentClass, string name)
{
    IComponent Component = null;

    Component = (IComponent)Activator.CreateInstance(componentClass);

    // Add to design container
    Add(Component, name);

    if (Component is UserControl newUC)
    {
        newUC.Visible = false;
        newUC.Visible = true;
    }

    return Component;
}

But this seems quite hack-ish to me.

0

There are 0 best solutions below