MVVM Light ViewModelLocator

rdo*_*don 6 xaml mvvm mvvm-light windows-phone-8

我在我的应用程序中使用MVVM Light,在解决方案中有多个程序集.如何在每个程序集中都没有ViewModelLocator,而无需在App.xaml资源中定义?

通常,ViewModelLocator的定义如下:

<Application.Resources>
  <ResourceDictionary>
   <ResourceDictionary.MergedDictionaries>
     <ResourceDictionary Source="/Sol1;component/GlobalResources.xaml" />
   </ResourceDictionary.MergedDictionaries>
   <viewModels:ViewModelLocator xmlns:main="clr-namespace:MainModule.ViewModel;assembly=MainModule" x:Key="Locator" d:IsDataSource="True"/> 
</ResourceDictionary>
Run Code Online (Sandbox Code Playgroud)

我在我的解决方案中的类库中创建了一个Resources.xaml,如下所示:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:ModuleX="clr-namespace:ModuleX">
<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="/Common;component/CommonResources.xaml" />
</ResourceDictionary.MergedDictionaries>
<ModuleX:ViewMoldelLocator x:Key="ModuleXLocator" />
</ResourceDictionary>
Run Code Online (Sandbox Code Playgroud)

但是,找不到ModuleXLocator:

<phone:PhoneApplicationPage
       ...
       DataContext="{Binding Main, Source={StaticResource ModuleXLocator}}">
Run Code Online (Sandbox Code Playgroud)

Jos*_*h C 6

如果我回答你的问题,我不是100%,但我会回答我遇到的类似问题及其解决方案.希望它是你正在寻找的.

问题:

您已经设计了一个精彩的小MVVMLight应用程序(LittleApp),现在您想将它用作另一个项目(BigApp)中的UserControl/Page/Window.问题是LittleApp在其相应的App.xaml中定义了ViewModelLocator,它不用于BigApp.结果是LittleApp在"BigApp的App.xaml"中查找其ViewModelLocator并失败.

您还希望将LittleApp作为独立项目工作,因此不要吝啬其设计.

给出可能的例外情况:

XMLParseException:无法找到LittleApp根节点中定义的ViewModelLocator(因为它在未使用的App.xaml中定义)

WPFError 40:您已经使用MVVMLight工具创建了两个应用程序,因此两个应用程序都有一个带有ViewModelLocator的App.xaml,名为"Locator",指向名为"Main"的ViewModel.LittleApp将能够解决这个问题,但它会指向错误的MainViewModel,因此会出现属性冲突.

解:

您需要将LittleApp的ViewModelLocator定义为LittleApp的MainView根节点中的资源.因此,如果您的MainView是名为LittleApp/View/MainView.xaml的UserControl,它将看起来像这样.

<UserControl x:Class="LittleApp.View.MainView"
         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:vm="clr-namespace:LittleApp.ViewModel"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">

    <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="../Skins/MainSkin.xaml" />
            </ResourceDictionary.MergedDictionaries>
            <vm:ViewModelLocator x:Key="Locator"/>
        </ResourceDictionary>
    </UserControl.Resources>

    <UserControl.DataContext>
        <Binding Source="{StaticResource Locator}"/>
    </UserControl.DataContext>

    <Grid>
       .
       .  Your Control Design
       .
       .
       .
    </Grid>
</UserControl>
Run Code Online (Sandbox Code Playgroud)

现在,BigApp只需要引用LittleApps程序集,并将其添加为要添加到其中的控件的根节点中的命名空间.像这样的东西.

<Page x:Class="BigApp.View.Page1"
      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:LittleView="clr-namespace:LittleApp.View;assembly=LittleApp"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300">

    <Grid>
        <LittleView:MainView/>
    </Grid>
</Page>
Run Code Online (Sandbox Code Playgroud)