在 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>
我希望这对其他人有帮助。
我正在查看专门针对 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>
我希望这对其他人有帮助。