有人可以快速总结一下ViewModelLocator是什么,它是如何工作的,以及与DataTemplates相比使用它的优缺点是什么?
我曾尝试在Google上查找信息,但似乎有许多不同的实现,并没有关于它是什么以及使用它的优点/缺点的严格列表.
这个问题可能看起来很幼稚,但我无法理解ViewModelLocator.cs文件中的这段代码:
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
if (ViewModelBase.IsInDesignModeStatic)
{
SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
}
else
{
SimpleIoc.Default.Register<IDataService, DataService>();
}
SimpleIoc.Default.Register<MainViewModel>();
}
Run Code Online (Sandbox Code Playgroud)
我看到我们使用DataService来获取数据(例如来自WCF服务)并将其分配给MainViewModel.但是,如果我注册了多个ViewModel怎么办?像这样:
static ViewModelLocator()
{
....
SimpleIoc.Default.Register<MainViewModel>();
SimpleIoc.Default.Register<Page2ViewModel>();
}
Run Code Online (Sandbox Code Playgroud)
并且假设我有另一个DataService(例如DataService2),但是这个我将与Page2ViewModel一起使用.我怎样才能做到这一点?
此外,如果有人可以帮助我(或甚至给我一个阅读链接)关于上述代码.我不知道这意味着什么.
我正在使用MVVMLight创建一个WPF应用程序.我使用ViewModelLocator来创建视图模型.我的问题是在它们之间传递参数.
例如,我们有一个情况:
我们有一个带有一些实体的网格,当其中一个被双击时,我需要创建一个包含该实体细节的新视图.如何将所选项ID发送到新View的ViewModel?
我需要能够拦截框架并在从缓存重新加载ViewModel时执行重新初始化.由于没有重新创建ViewModel,我既不能使用Init(),MvxViewModel.InitFromBundle,也不能使用MvxViewModel.ReloadFromBundle方法.
我正在尝试调试一种情况,单击后退按钮可以恢复状态不一致的ViewModel.某种MvxViewModel.OnReloading()会有所帮助.
有没有办法在v3中这样做?
编辑:
假设我有FirstPageViewModel,它公开了一个导航到SecondPageViewModel的命令.根据我观察的内容,如果在SecondPageView上单击模拟器的后退按钮,则不会构造FirstPageViewModel.相反,我相信它会从某个缓存中检索,然后绑定到View.此缓存可能是IMvxSingleViewModel缓存的实现.
因此,ViewModel构造之后的常规流(在此方案中调用Init(),InitFromBundle()和ReloadFromBundle()不适用.换句话说,我需要一种方法来重新初始化ViewModel,无论它是刚刚构建还是从缓存中复活.如果是前者,我可以使用Init()方法.如果后者为真,则无法在ViewModel本身内执行此操作.
这就是问题:
我有一个ICollectionService实例,它从FirstViewModel传递给SecondViewModel.FirstView还包含一个绑定到此CollectionService的ListView.因为CollectionService没有强类型,所以我可以传递它并使用适当的项模板在视图中呈现其项目.
在显示SecondViewModel之前,FirstViewModel检索一些远程数据并填充CollectionService.显示SecondViewModel时,其视图使用不同的项模板显示CollectionService中的数据.但是,如果我导航回来,由于FirstViewModel仍然引用CollectionService,FirstView将呈现SecondViewModel使用的数据,除非可以重新初始化FirstViewModel,清除过程中的CollectionService.也许这种方法是错误的,但这是我的问题的症结所在.
我不知道平台是否有所作为,因为我预计Windows Phone和iOS上会出现相同的行为,因为这种重新初始化将在Core模块中进行.尽管如此,这些都是对Android的观察.
TIA.
我已经使用Autofac创建了一个自定义视图模型定位器,并通过App.xaml正常设置它,就像通常使用它们一样.我的问题是我现在如何进行单元测试?每次我尝试测试初始化视图的方法时,我都会收到错误
在我的app.xaml中:
<desktop:ViewModelLocator xmlns:local="clr-namespace:MyProject.Desktop" x:Key="ViewModelLocator" />
Run Code Online (Sandbox Code Playgroud)
在每个视图中:
DataContext="{Binding MyFirstViewModel, Source={StaticResource ViewModelLocator}}"
Run Code Online (Sandbox Code Playgroud)
单元测试错误:
{"Cannot find resource named 'ViewModelLocator'. Resource names are case sensitive."}
Run Code Online (Sandbox Code Playgroud)
我明白为什么当你进行单元测试时,确实没有实际应用程序的实例,所以这个问题的好方法是什么?
ViewModelLocator代码:
/// <summary>
/// Autofac object container
/// </summary>
private readonly IContainer objectContainer;
#region Constructor
/// <summary>
/// Constructor for view model locator
/// </summary>
public ViewModelLocator()
{
objectContainer = App.ObjectContainer;
//objectContainer.BeginLifetimeScope();
}
#endregion
#region Properties
/// <summary>
/// Gets the resolved instance of a main window view model
/// </summary>
public MainWindowViewModel MainWindowViewModel
{
get
{ …Run Code Online (Sandbox Code Playgroud) 我在使用MVVMLight框架中的Messenger类在我的ViewModel之间传递参数时遇到问题.
这是我正在使用的代码:
ViewModelLocator
public ViewModelLocator ()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<INavigationService, NavigationService>();
SimpleIoc.Default.Register(() => new MainViewModel(NavigationService));
SimpleIoc.Default.Register(() => new SecondViewModel(NavigationService));
}
public MainViewModel MainViewModel
{
get { return SimpleIoc.Default.GetInstance<MainViewModel>(); }
}
public SecondViewModel SecondViewModel
{
get { return SimpleIoc.Default.GetInstance<SecondViewModel>(); }
}
public INavigationService NavigationService
{
get { return SimpleIoc.Default.GetInstance<INavigationService>(); }
}
Run Code Online (Sandbox Code Playgroud)
MainViewModel
private void ShowPersonDetailsCommand(object obj)
{
Messenger.Default.Send((Person)obj);
_navigationService.NavigateTo(new Uri("/SecondPage.xaml", UriKind.Relative))
}
Run Code Online (Sandbox Code Playgroud)
SecondViewModel
public SecondViewModel(INavigationService navigationService)
{
_navigationService = navigationService;
Messenger.Default.Register<Person>(
this,
person =>
{
Person = person;
});
} …Run Code Online (Sandbox Code Playgroud) c# silverlight mvvm-light viewmodellocator windows-phone-8.1
在使用MVVM的过去,我已经创建了每个View作为DataTemplate其对应的viewmodel来处理连接它们.我刚开始使用MVVM Light,并注意到他们有ViewModelLocator.我看过的其他几个工具包包含了一些变化,但这会带来什么好处DataTemplate呢?
连接Views和ViewModel的最佳做法是什么?
我正在建立一个Windows Phone 8.1项目,我正在使用MVVM Light Libraries only库.我创建了一个PCL项目来保存我的ViewModel,以便以后可以将它们用于Windows Store项目.
但我在标题中收到错误?
我的App.xaml
<Application
x:Class="Roadsmart.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Roadsmart"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels="clr-namespace:Roadsmart.Lib.ViewModels;assembly=Roadsmart.Lib"
mc:Ignorable="d">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/RoadSmartWindowsPhoneStyle.xaml"/>
<ResourceDictionary Source="Resources/Dictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
<viewModels:ViewModelLocator
x:Key="Locator"
d:IsDataSource="True"/>
</ResourceDictionary>
</Application.Resources>
</Application>
Run Code Online (Sandbox Code Playgroud)
我在Windows Phone项目中引用了Roadsmart.Lib.

我的Lib项目属性

但是Blend能够找到我的ViewModel吗?

但我无法建立,运行.我也试过清洗.

有人知道我做错了什么吗?
提前致谢
我希望自己实现ViewModelLocator.所以我实现了世界上最简单的应用程序.我做了本教程中的所有内容.但我仍然得到一个例外:
发生了XamlParseException
抛出异常:PresentationFramework.dll中的'System.Windows.Markup.XamlParseException'
附加信息:'为'System.Windows.StaticResourceExtension'提供价值引发了异常.行号'8'和行位置'9'.
这是这一行:
DataContext="{Binding MainWindowViewModel, Source={StaticResource ViewModelLocator}}">
Run Code Online (Sandbox Code Playgroud)
这是代码:
App.xaml中
<Application x:Class="ViewModelLocatorDemo.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewModelLocatorDemo="clr-namespace:ViewModelLocatorDemo">
<Application.Resources>
<viewModelLocatorDemo:ViewModelLocator x:Key="ViewModelLocator"/>
</Application.Resources>
</Application>
Run Code Online (Sandbox Code Playgroud)
App.xaml.cs
namespace ViewModelLocatorDemo
{
using System.Windows;
using ViewModelLocatorDemo.Views;
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
MainWindow mainWindow = new MainWindow();
mainWindow.Show();
}
}
}
Run Code Online (Sandbox Code Playgroud)
ViewModelLocator.cs
namespace ViewModelLocatorDemo
{
using ViewModels;
public class ViewModelLocator
{
public MainWindowViewModel MainWindowViewModel
{
get { return new MainWindowViewModel(); }
}
}
}
Run Code Online (Sandbox Code Playgroud)
MainWindow.xaml
<Window x:Class="ViewModelLocatorDemo.Views.MainWindow" …Run Code Online (Sandbox Code Playgroud) 我试图通过在 App.xaml 中将其声明为资源来使用 ViewModelLocator。它是一个非常简单的类,如下所示:
public class ViewModelLocator
{
public ShellViewModel ShellPage
{
get
{
return new ShellViewModel();
}
}
}
Run Code Online (Sandbox Code Playgroud)
App.xaml 文件如下:
<Application x:Class="SomeNamespace.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:SomeNamespace.ViewModels">
<Application.Resources>
<vm:ViewModelLocator x:Key="ViewModelLocator" />
</Application.Resources>
</Application>
Run Code Online (Sandbox Code Playgroud)
App.xaml.cs 如下:
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var view = new ShellView();
Current.MainWindow = view;
Current.MainWindow.Show();
}
}
Run Code Online (Sandbox Code Playgroud)
ShellView.xaml 如下:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SomeNamespace.ShellView"
Title="MainWindow"
Height="350"
Width="525"
ResizeMode="NoResize"
MinWidth="700"
MinHeight="700"
DataContext="{Binding ShellPage, Source={StaticResource ViewModelLocator}}"
>
<Grid>
<TextBlock Text="{Binding …Run Code Online (Sandbox Code Playgroud) viewmodellocator ×10
mvvm ×7
wpf ×7
c# ×4
mvvm-light ×4
.net ×2
datatemplate ×2
silverlight ×2
viewmodel ×2
xaml ×2
mvvmcross ×1
unit-testing ×1