在 xaml 中设置 RegionName 时,使用 MefBootstrapper 在 WPF 应用程序中激活/停用视图会抛出异常

Activate / deactivate views in WPF app using MefBootstrapper throws exception when setting the RegionName in xaml

我正在查看专门针对 https://github.com/PrismLibrary/Prism-Samples-Wpf/tree/master/6-ViewActivationDeactivation 的 PrismLibrary 的 WPF 示例。我的目标是创建 ViewActivationDeactivation 解决方案的工作版本,但使用 MefBootstrapper 而不是示例中最初使用的 UnityBoostrapper。

我已经像这样配置了我的引导程序class

public class Bootstrapper : MefBootstrapper
{
    protected override void ConfigureAggregateCatalog()
    {
        AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(Bootstrapper).Assembly));
        base.ConfigureAggregateCatalog();
    }
    protected override DependencyObject CreateShell()
    {
        return Container.GetExportedValue<MainWindow>();
    }

    protected override void InitializeShell()
    {
        Application.Current.MainWindow = (MainWindow)Shell;
        Application.Current.MainWindow.Show();
    }

    protected override CompositionContainer CreateContainer()
    {
        var container = base.CreateContainer();
        container.ComposeExportedValue(container);
        return container;
    }
}

MainWindow 的代码如下所示:

xaml

<Window x:Class="DuoApp_ViewNav.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DuoApp_ViewNav"
        xmlns:v="clr-namespace:DuoApp_ViewNav.Views"
             xmlns:prism="http://prismlibrary.com/"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <DockPanel LastChildFill="True">
        <ContentControl prism:RegionManager.RegionName="ContentRegion" HorizontalAlignment="Center" VerticalAlignment="Center" />
    </DockPanel>
</Window>

xaml.cs

[Export]
public partial class MainWindow : Window
{
    private CompositionContainer _container;
    private IRegionManager _regionManager;
    IRegion _region;

    ViewA _viewA;
    ViewB _viewB;

    [ImportingConstructor]
    public MainWindow(CompositionContainer container, IRegionManager regionManager)
    {
        InitializeComponent();
        _container = container;
        _regionManager = regionManager;

        this.Loaded += MainWindow_Loaded;
    }

    private void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        _viewA = _container.GetExportedValue<ViewA>();
        _viewB = _container.GetExportedValue<ViewB>();

        _region = _regionManager.Regions["ContentRegion"];

        _region.Add(_viewA);
        _region.Add(_viewB);
    }
}

我面临的问题是 MainWindow 无法初始化,当尝试在 ContentControl 中设置 RegionName 时抛出 System.Windows.Markup.XamlParseException 内部异常消息是

Activation error occurred while trying to get instance of type DelayedRegionCreationBehavior, key ""

这里是异常的完整详细信息

System.Windows.Markup.XamlParseException occurred
HResult=-2146233087 LineNumber=12 LinePosition=10 Message='Set property 'Prism.Regions.RegionManager.RegionName' threw an exception.' Line number '12' and line position '10'.
Source=PresentationFramework StackTrace: at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri) at System.Windows.Markup.WpfXamlLoader.LoadBaml(XamlReader xamlReader, Boolean skipJournaledProperties, Object rootObject, XamlAccessLevel accessLevel, Uri baseUri) at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream) at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator) at DuoApp_ViewNav.MainWindow.InitializeComponent() in C:\Users\ralfaro\Documents\Visual Studio 2015\Projects\DuoApp_ViewNav\DuoApp_ViewNav\MainWindow.xaml:line 1
InnerException: HResult=-2146233088 Message=Activation error occurred while trying to get instance of type DelayedRegionCreationBehavior, key "" Source=Microsoft.Practices.ServiceLocation StackTrace: at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type serviceType, String key) in c:\Projects\CommonServiceLocator\main\Microsoft.Practices.ServiceLocation\ServiceLocatorImplBase.cs:line 53 at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstanceTService in c:\Projects\CommonServiceLocator\main\Microsoft.Practices.ServiceLocation\ServiceLocatorImplBase.cs:line 90 at Prism.Regions.RegionManager.CreateRegion(DependencyObject element) at Prism.Regions.RegionManager.OnSetRegionNameCallback(DependencyObject element, DependencyPropertyChangedEventArgs args) at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e) at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e) at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args) at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType) at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal) at System.Windows.Baml2006.WpfMemberInvoker.SetValue(Object instance, Object value) at MS.Internal.Xaml.Runtime.ClrObjectRuntime.SetValue(XamlMember member, Object obj, Object value) at MS.Internal.Xaml.Runtime.ClrObjectRuntime.SetValue(Object inst, XamlMember property, Object value) InnerException: HResult=-2146233088 Message=Activation error occurred while trying to get instance of type DelayedRegionCreationBehavior, key "" Source=Microsoft.Practices.Prism.MefExtensions StackTrace: at Microsoft.Practices.Prism.MefExtensions.MefServiceLocatorAdapter.DoGetInstance(Type serviceType, String key) at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type serviceType, String key) in c:\Projects\CommonServiceLocator\main\Microsoft.Practices.ServiceLocation\ServiceLocatorImplBase.cs:line 49 InnerException:

老实说,我不知道为什么会抛出这个异常。我是否遗漏了一些让 MefBootstrapper 可以正常工作的东西?

终于想通了。我错误地引用了两个具有 MefBootstrapper 实现的程序集,Prism.Mef 和 Prism.MefExtensions。删除 Prism.MefExtensions package/reference 后,应用程序开始正常运行。 我发现非常有用和有用的最后一个故障排除步骤是 运行 本地 Prism 库代码并从那里添加所需的引用,这让我认识到不需要 MefExtensions。

我的 packages.config 文件的当前版本如下所示:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="CommonServiceLocator" version="1.3" targetFramework="net461" />
  <package id="Prism.Core" version="6.3.0" targetFramework="net461" />
  <package id="Prism.Mef" version="6.3.0" targetFramework="net461" />
  <package id="Prism.Wpf" version="6.3.0" targetFramework="net461" />
</packages>

我希望这对其他人有帮助。