【问题标题】:Prism 6.1 ViewModelLocator doesn't instantiate my ViewModelPrism 6.1 ViewModelLocator 没有实例化我的 ViewModel
【发布时间】:2016-03-04 09:17:23
【问题描述】:

我最近刚刚建立了一个新项目,使用的是 Prism 6.1(带有 Unity)。

我有我的引导程序:

public class ServerBootstrapper : UnityBootstrapper
{
    protected override DependencyObject CreateShell()
    {
        return Container.Resolve<MainShell>();
    }
    protected override void InitializeShell()
    {
        base.InitializeShell();
        Application.Current.MainWindow = (Window)Shell;
        Application.Current.MainWindow.Show();
    }
    protected override void ConfigureModuleCatalog()
    {
        base.ConfigureModuleCatalog();
        ModuleCatalog catalog = (ModuleCatalog)ModuleCatalog;
        catalog.AddModule(typeof(ServerUIModule));
    }
}

MainShell:

<Window.Resources>
    <Style TargetType="TabItem">
        <Setter Property="Header" Value="{Binding DataContext.Title}" />
    </Style>
</Window.Resources>
<DockPanel LastChildFill="True">
    <TabControl regions:RegionManager.RegionName="{x:Static infrastructure:RegionsNames.MAIN_TAB_REGION}" />
</DockPanel>

我的模块定义:

public class ServerUIModule : IModule
{
    private readonly IRegionManager m_regionManager;

    public ServerUIModule( IRegionManager regionManager)
    {
        m_container = container;
        m_regionManager = regionManager;
    }

    public void Initialize()
    {
        m_regionManager.RegisterViewWithRegion(RegionsNames.MAIN_TAB_REGION, typeof(StatusView));
        m_regionManager.RegisterViewWithRegion(RegionsNames.MAIN_TAB_REGION, typeof(LogMessagesView));
    }
}

我的状态视图:

<UserControl x:Class="Xms.Server.UI.Views.StatusView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Xms.Server.UI.Views"
             xmlns:mvvm="http://prismlibrary.com/"
             xmlns:statusControl="clr-namespace:Xms.Server.UI.Views.StatusControl"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300" Background="Aquamarine" mvvm:ViewModelLocator.AutoWireViewModel="True">
    <Grid>
        <TextBlock>Content</TextBlock>
    </Grid>
</UserControl>

对应的ViewModel:

public class StatusViewModel : BindableBase
{
    public String Title => LocalizedResources.StatusModuleTitle;

    public StatusViewModel()
    {
        //This constructor is never called
    }
}

问题是我的构造函数从未被调用,我的 DataContext 未设置。

我该如何调试呢?我做错了什么?

【问题讨论】:

  • StatusView 已创建但未创建 StatusViewModel?
  • @Haukinger 没错,但使用ViewModelLocator.AutoWireViewModel="True" 应该会找到与View 匹配的ViewModel(6.1 约定是将“Model”添加到“XxxxView”以搜索类)。但是我找不到任何日志表明它找不到它,...

标签: c# .net wpf prism viewmodellocator


【解决方案1】:

首先,确保视图位于 Views 命名空间中,视图模型分别位于 ViewModels 中。

其次,调试此类事情的最简单方法是从 prism 源中复制一些代码并将其放入 MyBootstrapper.ConfigureContainer

ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver( x =>
                                                                     {
                                                                         var viewName = x.FullName;
                                                                         viewName = viewName.Replace( ".Views.", ".ViewModels." );
                                                                         var viewAssemblyName = x.GetTypeInfo().Assembly.FullName;
                                                                         var suffix = viewName.EndsWith( "View" ) ? "Model" : "ViewModel";
                                                                         var viewModelName = string.Format( CultureInfo.InvariantCulture, "{0}{1}, {2}", viewName, suffix, viewAssemblyName );
                                                                         return Type.GetType( viewModelName );
                                                                     } );
ViewModelLocationProvider.SetDefaultViewModelFactory( type => Container.Resolve( type ) );

...并在那里放置断点以查看究竟是什么问题。或者,在大约第三级挖掘您的XamlParseExceptionInnerExceptions...,您应该会找到真正的问题。但我发现我的断点方法更方便。

【讨论】:

  • Views/ViewsModels 命名空间错误。这对 Prism 5 来说是正确的,但是根据他们的发行说明,我知道他们改变了他们的默认命名约定?我会测试你的代码(但我想它应该放在ConfigureViewModelLocator,而不是ConfigureContainer
  • 好吧,看来我误解了惯例的改变(Brian Lagunas 建议改变惯例,因为他是新主人,我以为是按照他自己的建议。反正我改变了我自己约定,现在一切正常。
猜你喜欢
  • 2011-08-18
  • 1970-01-01
  • 1970-01-01
  • 2016-01-05
  • 1970-01-01
  • 1970-01-01
  • 2016-04-04
  • 1970-01-01
  • 2016-01-08
相关资源
最近更新 更多