【问题标题】:Displaying modules in a Prism region when available可用时在 Prism 区域中显示模块
【发布时间】:2011-01-06 18:23:45
【问题描述】:

我想在我的应用程序加载时加载模块,并让它们将视图放入 Shell(主视图)中的 region(另请参阅 this MSDN article)。我目前正在按需加载一个模块,它工作得很好。 (我使用调用this.moduleManager.LoadModule("ModuleB"); 的按钮加载模块,其中moduleManager 定义为[Import(AllowRecomposition = false)] private IModuleManager moduleManager;。这一切都来自ModularityWithMef.Desktop 示例应用程序。)以下是相关代码:

模块

[ModuleExport(typeof(ModuleB), InitializationMode = InitializationMode.OnDemand)]
public class ModuleB : IModule
{
    [Import(AllowRecomposition = false)] private IRegionManager _regionManager;

    /// <summary>
    /// Initializes a new instance of the <see cref="ModuleB"/> class.
    /// </summary>
    public ModuleB()
    {
    }

    /// <summary>
    /// Notifies the module that it has be initialized.
    /// </summary>
    public void Initialize()
    {
        _regionManager.AddToRegion("ContentRegion", new ModuleBView());
    }
}

XAML 区域

<TabControl Regions:RegionManager.RegionName="ContentRegion" />

当我更改为在可用时加载模块 ([ModuleExport(typeof(ModuleB), InitializationMode = InitializationMode.WhenAvailable)]),当引导程序创建 Shell 时,我会收到 ModuleInitializeException,说“此 RegionManager 不包含名为 'ContentRegion' 的区域”。这告诉我在 Shell 中创建区域和初始化模块存在时间问题。

所以这是我的问题:如何在发现时将模块的视图注册到 Shell 的区域,而无需使用 OnDemand 初始化和手动加载模块?

【问题讨论】:

    标签: .net wpf module prism mef


    【解决方案1】:

    嗯,这是一个简单的答案,但出于某种原因,我很难找到。 IRegionManager 提供了一个 RegisterViewWithRegion 方法,该方法接受一个返回视图的函数。这允许区域管理器在视图准备好时实例化视图(而不是使用AddToRegion,它会立即发生)。所以关键是在模块的Initialize 例程中使用该方法:

    public void Initialize()
    {
        _regionManager.RegisterViewWithRegion("ContentRegion", () => new ModuleBView());
    }
    

    在解决这个问题的同时,我也想出了一个解决方法。当模块设置为InitializationMode.OnDemand 时,Shell 可以导入IModuleManager 并在ContentRendered 事件中使用LoadModule。这确保了区域已添加到区域管理器中,并且模块可以毫无问题地添加其视图。如果您需要遍历可用模块,请使用此事件处理程序:

    public Shell()
    {
        InitializeComponent();
    
        ContentRendered += (o, eventArgs) =>
            {
                foreach (var moduleInfo in _moduleCatalog.Modules)
                {
                    _moduleManager.LoadModule(moduleInfo.ModuleName);
                }
            };
    }
    

    【讨论】:

    • 感谢发帖。 :)
    【解决方案2】:

    我倾向于在引导程序中为 Views 和 Region 带来快乐,在 AggregateCatalog.Changed _handler - 这是你知道你的模块已经加载并且Shell已经用所有模块实例化的地方。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-08
      • 1970-01-01
      • 1970-01-01
      • 2011-04-27
      • 1970-01-01
      相关资源
      最近更新 更多