Как использовать Prism в ElementHost - PullRequest
1 голос
/ 01 сентября 2009

Я новичок в 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 ]

4 голосов
/ 01 сентября 2009

Причина в том, что этот код в 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!

Решение:

  1. Создайте пустой класс, который будет наследоваться от 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).

0 голосов
/ 04 февраля 2014

@ Марк Линделл Выше работал на меня. Единственное, что мне пришлось изменить, это ниже.

Мой загрузчик

 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 (формы) должен быть создан щелкните правой кнопкой мыши форму, в окне свойств перейдите к событиям и дважды нажмите Загрузить. Копирование и вставка обработчика событий загрузки не работает.

...