wpf 在 MVVM Light Toolkit 中向 ViewModelLocator 添加一个新的 ViewModel
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17978082/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Add a New ViewModel to ViewModelLocator in MVVM Light Toolkit
提问by DanteTheEgregore
I know this question is somewhat basic, but at the current moment, I am completely lost as to how I should add a new ViewModel to my ViewModelLocator class in MVVMLight Toolkit.
我知道这个问题有点基础,但目前,我完全不知道应该如何将新的 ViewModel 添加到MVVMLight Toolkit 的ViewModelLocator 类中。
My current implementation looks like so:
我目前的实现看起来像这样:
First assume that I have a Window named Settings, a ViewModel named SettingsViewModeland a ViewModelLocator ViewModelLocator.
首先假设我有一个名为 的 Window Settings,一个名为 ViewModelSettingsViewModel和一个 ViewModelLocator ViewModelLocator。
First I call CreateSettings()in the VieModelLocator constructor:
首先我调用CreateSettings()VieModelLocator 构造函数:
public ViewModelLocator()
{
if (ViewModelBase.IsInDesignModeStatic)
{
}
else
{
CreateSettings();
}
CreateMain();
}
Note that this will always run as I'm not using blend and build the application each time I try to run it. Now for the `CreateSettings() method.
请注意,这将始终运行,因为我每次尝试运行它时都没有使用混合和构建应用程序。现在是`CreateSettings() 方法。
I had no idea what I was doing so I tried to play it safe and model everything after the methods used for creating and managing the MainViewModel.
我不知道我在做什么,所以我尝试安全地使用它,并按照用于创建和管理 MainViewModel 的方法对所有内容进行建模。
public static void CreateSettings()
{
if (_settings == null)
{
_settings = new SettingsViewModel();
}
}
Then another few methods modeled after those used for the MainViewModel:
然后还有一些方法模仿了 MainViewModel 使用的方法:
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
"CA1822:MarkMembersAsStatic",
Justification = "This non-static member is needed for data binding purposes.")]
public SettingsViewModel Settings
{
get
{
return SettingsStatic;
}
}
public static SettingsViewModel SettingsStatic
{
get
{
if (_settings == null)
{
CreateSettings();
}
return _settings;
}
}
And in my SettingsWindow Xaml:
在我的Settings窗口 Xaml 中:
<Window x:Class="_5500A_Auto_Calibrator.Settings"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Settings" Height="300" Width="300"
DataContext="{Binding Source={StaticResource Locator}, Path=Settings}">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Skins/MainSkin.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
The window is then opened from my MainViewModel like so:
然后从我的 MainViewModel 打开窗口,如下所示:
Settings settings = new Settings();
settings.Show();
If I try this, I receive an exception:
如果我尝试这个,我会收到一个异常:
"'Provide value on 'System.Windows.StaticResourceExtension' threw an exception.' Line number '4' and line position '39'."
And an inner exception of:
还有一个内部例外:
"Cannot find resource named 'Locator'. Resource names are case sensitive."
I've read up on errors involving a Window's inability to find the Locatorresource, but most have to do with blend.
我已经阅读了涉及 Window 无法找到Locator资源的错误,但大多数都与混合有关。
My current take is that I'm doing something wrong, but there's so little documentation as to adding new ViewModels that I'm unsure what I'm doing wrong.
我目前的看法是我做错了什么,但是关于添加新 ViewModel 的文档太少了,我不确定我做错了什么。
Edit:
编辑:
My App.Xaml:
我的 App.Xaml:
<Application x:Class="_5500A_Auto_Calibrator.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:_5500A_Auto_Calibrator.ViewModel"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
StartupUri="MainWindow.xaml"
mc:Ignorable="d">
<Application.Resources>
<!--Global View Model Locator-->
<vm:ViewModelLocator x:Key="Locator"
d:IsDataSource="True" />
</Application.Resources>
</Application>
回答by Noctis
This is how it usually looks:
这是它通常的样子:
public class ViewModelLocator
{
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>();
}
/// <summary>
/// Gets the Main property.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
"CA1822:MarkMembersAsStatic",
Justification = "This non-static member is needed for data binding purposes.")]
public MainViewModel Main
{
get
{
return ServiceLocator.Current.GetInstance<MainViewModel>();
}
}
...
}
the ViewModelLocator is static, yours doesn't seem to be. It usually sits in the ViewModel folder (assuming you installed mvvmlight with the nuget and then added a new wvvm project.
ViewModelLocator 是静态的,你的似乎不是。它通常位于 ViewModel 文件夹中(假设您使用 nuget 安装了 mvvmlight,然后添加了一个新的 wvvm 项目。
it then proceeds to have the 2 cases for design and for runtime. (if you don't use it, you can skip the if (IsInDesignMode) ...bit, and just put your logic. (though it's a shame, since it's nice to have a preview of some fake data in VS designer ...)
然后它继续为设计和运行时提供 2 个案例。(如果你不使用它,你可以跳过这if (IsInDesignMode) ...一点,把你的逻辑。(虽然很遗憾,因为在VS设计器中预览一些假数据很好......)
Adding new ViewModels usually involves creating a property of that type, and registering them with the locator, so you can then retrieve them ... but this differs and can be done differently I believe ...
添加新的 ViewModel 通常涉及创建该类型的属性,并将它们注册到定位器,这样您就可以检索它们……但这有所不同,我相信可以以不同的方式完成……
Hope this help, and if there's anything else I can help with, do let me know.
希望这会有所帮助,如果还有什么我可以帮忙的,请告诉我。
回答by Dennis
Your data context binding tries to apply earlier, than resource is declared. Try to declare binding this way (of course, this should help only if either MainSkin.xamlor application resources contain Locatorresource):
您的数据上下文绑定尝试在资源声明之前应用。尝试以这种方式声明绑定(当然,这应该仅在MainSkin.xaml应用程序资源或应用程序资源包含Locator资源时才有帮助):
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Skins/MainSkin.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Window.DataContext>
<Binding Source="{StaticResource Locator}" Path="Settings"/>
</Window.DataContext>

