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.
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.