Как использовать Prisim в ElementHost
Я новичок в Prism и пытаюсь разместить элемент управления Prisim в ElementHost. Кажется, мне не хватает чего-то очень простого. У меня есть одна WinForm, которая содержит ElementHost. Следующий код находится в форме:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Bootstrapper bootstrapper = new Bootstrapper();
bootstrapper.Run();
var child = bootstrapper.Container.Resolve<Shell>();
elementHost.Child = child;
}
BootStrapper управляет регистрацией
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;
}
}
На данный момент MyView.xaml является не чем иным, как меткой.
Shell.xaml - это UserControl, который содержит следующий XAML:
<ItemsControl Name="MainRegion" cal:RegionManager.RegionName="MainRegion" />
Код модуля минимален:
public class MyModule : IModule
{
private readonly IRegionViewRegistry _regionViewRegistry;
public MyModule(IRegionViewRegistry registry)
{
_regionViewRegistry = registry;
}
public void Initialize()
{
_regionViewRegistry.RegisterViewWithRegion("MainRegion", typeof(MyView));
}
}
Я глубоко прослеживал код Prism, пытаясь выяснить, почему представление никогда не устанавливается в регионе. Я что-то упустил?
2 ответа
Причина в том, что этот код в 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);
}
Причина в том, что для приложения без WPF Application.Current имеет значение NULL!
Решение:
- Создайте пустой класс, который будет наследоваться от System.Windows.Application. (Имя не имеет значения):
В точке входа в плагин выполните следующий код:
public class MyApp : System.Windows.Application
{
}
if (System.Windows.Application.Current == null)
{
// create the Application object
new MyApp();
}
Вот и все - теперь у вас есть Application.Current, который не равен нулю и не равен typeof(Application).
@ Марк Линделл Выше работал на меня. Единственное, что мне пришлось изменить, это ниже.
Мой загрузчик
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));
}
и мой класс формы
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);
}
}
}
И чтобы было ясно, я добавил класс ниже в приложении WPF PRISM, содержащем Shell.
public class MyApp : System.Windows.Application
{
}
Редактировать: Обратите внимание, что обработчик метода Load (формы) должен быть создан путем щелчка правой кнопкой мыши по форме. В окне свойств перейдите к событиям и дважды щелкните Load. Копирование и вставка обработчика событий загрузки не работает.