Cómo utilizar Prism dentro de un ElementHost
Pregunta
Soy nuevo en Prism y yo estoy tratando de albergar un control prisim dentro de un ElementHost. Parece que estoy perdiendo algo muy básico. Tengo una sola WinForm que contiene un ElementHost. El código siguiente es de la forma:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Bootstrapper bootstrapper = new Bootstrapper();
bootstrapper.Run();
var child = bootstrapper.Container.Resolve<Shell>();
elementHost.Child = child;
}
El programa previo maneja 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;
}
}
El MyView.xaml es nada más que una etiqueta en este punto.
Shell.xaml es un control de usuario que contiene la siguiente XAML:
<ItemsControl Name="MainRegion" cal:RegionManager.RegionName="MainRegion" />
El código del módulo es mínimo:
public class MyModule : IModule
{
private readonly IRegionViewRegistry _regionViewRegistry;
public MyModule(IRegionViewRegistry registry)
{
_regionViewRegistry = registry;
}
public void Initialize()
{
_regionViewRegistry.RegisterViewWithRegion("MainRegion", typeof(MyView));
}
}
He estado rastreando profundamente en el código Prisma tratando de averiguar por qué la vista no se ajusta a la región. Me estoy perdiendo algo básico?
Solución
La razón es el código de 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);
}
La razón es que para la aplicación de WPF no es NULL el Application.Current!
La solución:
- Crea una clase vacía que va a heredar de System.Windows.Application. (El nombre no importa):
En el punto de entrada a un plug-in ejecute el siguiente código:
public class MyApp : System.Windows.Application
{
}
if (System.Windows.Application.Current == null)
{
// create the Application object
new MyApp();
}
Esto es todo -. Ahora usted tiene una Application.Current que no es nulo y no es igual a typeof (Aplicación)
Otros consejos
@ Marcos Lindell encima trabajó para mí. Las únicas cosas que tenía que cambiar son a continuación.
Mi programa previo
public class Bootstrapper : UnityBootstrapper
{
protected override DependencyObject CreateShell()
{
return this.Container.Resolve<Shell>();
}
protected override void InitializeShell()
{
base.InitializeShell();
if (System.Windows.Application.Current == null)
{
// create the Application object
new HelloWorld.Myapp();
}
//App.Current.MainWindow = (Window)this.Shell;
//App.Current.MainWindow.Show();
//MainWindow = (Window)this.Shell;
}
protected override void ConfigureModuleCatalog()
{
base.ConfigureModuleCatalog();
ModuleCatalog moduleCatalog = (ModuleCatalog)this.ModuleCatalog;
moduleCatalog.AddModule(typeof(HelloWorldModule.HelloWorldModule));
}
y mi forma de clase
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//Create the ElementHost control for hosting the WPF UserControl
ElementHost host = new ElementHost();
host.Dock = DockStyle.Fill;
Bootstrapper bootstrapper = new Bootstrapper();
bootstrapper.Run(true);
//var uc = bootstrapper.Container.Resolve<Shell>(); This line threw error
//Create the WPF UserControl.
HelloWorld.Shell uc = new HelloWorld.Shell();
//Assign the WPF UserControl to the ElementHost control's Child property.
host.Child = uc;
//Add the ElementHost control to the form's collection of child controls.
this.Controls.Add(host);
}
}
}
Y para ser claros, añadí inferior a la clase en la aplicación de WPF que contiene PRISM Shell.
public class MyApp : System.Windows.Application
{
}
Edit: Tenga en cuenta que el controlador de métodos de carga (de forma) tiene que ser creado por el botón derecho en la forma, en la ventana de propiedades, ir a eventos y doble Cargar clicl. manejador de copiar y pegar carga evento no funciona.