【问题标题】:How to use Prism within an ElementHost如何在 ElementHost 中使用 Prism
【发布时间】:2010-11-24 16:53:10
【问题描述】:

我是 Prism 的新手,我正在尝试在 ElementHost 中托管一个 Prisim 控​​件。我似乎遗漏了一些非常基本的东西。我有一个包含 ElementHost 的 WinForm。以下代码的形式为:

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 是一个包含以下 XAML 的 UserControl:

<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 代码,试图找出为什么视图从未设置到该区域中。我错过了一些基本的东西吗?

【问题讨论】:

    标签: wpf prism cal cag


    【解决方案1】:

    原因是 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();
    }
    

    就是这样——现在你有一个不为空且不等于 typeof(Application) 的 Application.Current。

    【讨论】:

      【解决方案2】:

      @Mark Lindell 以上为我工作。我唯一需要改变的地方如下。

      我的引导程序

       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);
              }
          }   
      
      
              }
      

      为了清楚起见,我在包含 Shell 的 WPF PRISM 应用程序中添加了下面的类。

      public class MyApp : System.Windows.Application
      {
      }
      

      编辑:请注意,加载方法处理程序(表单)必须由 右键单击表单,在属性窗口中,转到事件并双击 单击加载。复制和粘贴加载事件处理程序不起作用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多