wpfprismcalcag

How to use Prism within an ElementHost


I'm new to Prism and I am attempting to host a Prisim control within an ElementHost. I seem to be missing something very basic. I have a single WinForm that contains an ElementHost. The following code is in the form:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        Bootstrapper bootstrapper = new Bootstrapper();
        bootstrapper.Run();

        var child = bootstrapper.Container.Resolve<Shell>();
        elementHost.Child = child;

    }

The BootStrapper handles regisration

public class Bootstrapper : UnityBootstrapper
{
    protected override DependencyObject CreateShell()
    {
        Container.RegisterType<MyView>();
        var shell = Container.Resolve<Shell>();
        return shell;
    }

    protected override IModuleCatalog GetModuleCatalog()
    {
        ModuleCatalog catalog = new ModuleCatalog();
        catalog.AddModule(typeof(MyModule));
        return catalog;
    }
}

The MyView.xaml is nothing more than a label at this point.

Shell.xaml is a UserControl that contains the following XAML:

<ItemsControl Name="MainRegion" cal:RegionManager.RegionName="MainRegion" />

The module code is minimal:

public class MyModule : IModule
{
    private readonly IRegionViewRegistry _regionViewRegistry;

    public MyModule(IRegionViewRegistry registry)
    {
        _regionViewRegistry = registry;   
    }

    public void Initialize()
    {
        _regionViewRegistry.RegisterViewWithRegion("MainRegion", typeof(MyView));
    }
}

I've been tracing deep into the Prism code trying to figure out why the View is never set into the region. Am I missing something basic?


Solution

  • The reason is this code in Prism:

    private static bool RegionManager::IsInDesignMode(DependencyObject element)
    {
        // Due to a known issue in Cider, GetIsInDesignMode attached property value is not enough to know if it's in design mode.
        return DesignerProperties.GetIsInDesignMode(element) || Application.Current == null
            || Application.Current.GetType() == typeof(Application);
    }
    

    The reason is that for the non-WPF application the Application.Current is NULL!

    The solution:

    1. Create an empty class that will inherit from System.Windows.Application. (Name doesn’t matter):

    At the point of entry to a plug-in execute the following code:

    public class MyApp : System.Windows.Application
    {
    }
    
    if (System.Windows.Application.Current == null)
    {
        // create the Application object
        new MyApp();
    }
    

    This is it – now you have an Application.Current that is not null and it’s not equal to typeof(Application).