是否可以在UserControl上使用MVVMLight ViewModelLocator。 我已将其添加到我的用户控件中,方法与在MainWindow上完成相同,但我在VS2010中收到错误/弹出窗口,指出“无法找到名为'Locator'的资源。资源名称区分大小写。”
有没有人试过这个?
到目前为止,我的代码是一个标准的MVVMLight WPF入门应用程序...
用户控件
<UserControl x:Class="NavTest3.PersonControl"
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"
mc:Ignorable="d"
Height="116" MinWidth="250" Width="300"
DataContext="{Binding Person, Source={StaticResource Locator}}"
>
<!---->
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Skins/MainSkin.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
App.xaml包含..
<Application.Resources>
<!--Global View Model Locator-->
<vm:ViewModelLocator x:Key="Locator"
d:IsDataSource="True" />
</Application.Resources>
所以问题在于在userControl上设置“DataContext =”{Binding Person,Source = {StaticResource Locator}}“。
如上所述,这样做意味着此用户控件的每个实例都将共享相同的ViewModel,但我想在开始之前先理解这个问题。
答案 0 :(得分:3)
是的,您可以在用户控件中创建静态资源
<UserControl x:Class="MvvmLight1.UserControl1"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
xmlns:vm="clr-namespace:MvvmLight1.ViewModel"
>
<UserControl.Resources>
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
</UserControl.Resources>
<Grid>
</Grid>
</UserControl>
但IMO对于UserControles使用MVVM Light ViewModelLocator并不是一个好主意,因为它是一个静态属性,当您要实例化用户控件的多个实例时,将会有相同的常见ViewModel,所以它们都是相同的如果您决定在整个项目中使用一次,那么这不是我们想要的UserControl。
要解决此问题,您需要通过使所有属性非静态来修改ViewModelLocator,例如:
public class ViewModelLocator
{
// v--- You got to comment this out
private /*static*/ MainViewModel _main;
public ViewModelLocator()
{
CreateMain();
}
public /*static*/ MainViewModel MainStatic
{
get
{
if (_main == null)
{
CreateMain();
}
return _main;
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
"CA1822:MarkMembersAsStatic",
Justification = "This non-static member is needed for data binding purposes.")]
public MainViewModel Main
{
get
{
return MainStatic;
}
}
public /*static*/ void ClearMain()
{
_main.Cleanup();
_main = null;
}
public /*static*/ void CreateMain()
{
if (_main == null)
{
_main = new MainViewModel();
}
}
public /*static*/ void Cleanup()
{
ClearMain();
}
}
答案 1 :(得分:2)
加载资源的顺序可能有问题...尝试分配层次结构中较低元素的DataContext,例如,用户控件下面的网格。
<UserControl x:Class="NavTest3.PersonControl"
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"
mc:Ignorable="d" Height="116" MinWidth="250" Width="300">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Skins/MainSkin.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid DataContext="{Binding Person, Source={StaticResource Locator}}">
<!-- content -->
</Grid>
</UserControl>
修改:
尝试使用Visual Studio的属性部分中的数据绑定来设置绑定并确认您看到了Locator。选择DataContext应该到达的元素,找到DataContext属性,然后单击属性值区域。现在应打开一个对话框,您可以在其中选择定位器。可能这可以解决问题,或者帮助你找到灵魂。还要在绑定之前重建项目。
答案 2 :(得分:0)
确认您的某个ViewModel中没有抛出异常。通常当我收到该错误时,无法实例化Locator,因为上游Viewmodel构建之一会抛出异常。你可以发布你的Locator构造函数吗?
如果您想自己解决这个问题,请在VMLocator中的第一个CreateVM语句上设置一个断点,看看哪个VM引发了异常。