首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MVVMLight ViewModelLocator on a UserControl

MVVMLight ViewModelLocator on a UserControl
EN

Stack Overflow用户
提问于 2011-06-13 10:04:26
回答 3查看 10.2K关注 0票数 4

是否可以在MVVMLight ViewModelLocator上使用UserControl。我以与MainWindow相同的方式将它添加到我的用户控件中,但是我在VS2010中得到一个错误/弹出,声明“无法找到名为'Locator‘的资源。资源名是区分大小写的。”

有人试过这个吗?

到目前为止,我的代码基本上是一个标准的MVVMLight WPF初学者应用程序.

UserControl

代码语言:javascript
复制
<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包含..。

代码语言:javascript
复制
<Application.Resources>
    <!--Global View Model Locator-->
    <vm:ViewModelLocator x:Key="Locator"
                         d:IsDataSource="True" />
</Application.Resources>

因此,问题在于将"DataContext="{Binding Person,Source={StaticResource Locator}“设置在userControl上。”

如前所述,这样做将意味着此用户控件的每个实例都将共享相同的ViewModel,但在继续之前,我想先了解这个问题。

EN

回答 3

Stack Overflow用户

发布于 2011-06-14 07:58:06

是的,可以,您需要在用户控件中创建静态资源。

代码语言:javascript
复制
<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>

但是,海事组织使用MVVM进行UserControles并不是一个好主意,因为它是一个静态属性,当您要实例化用户控件的多个实例时,将有相同的公共ViewModel,因此它们的操作都是相同的,如果您决定在整个项目中使用它一次,那么这并不是我们希望的UserControl。

要解决这个问题,您需要修改ViewModelLocator,例如,将所有属性非静态化:

代码语言:javascript
复制
 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();
        }
    }
票数 4
EN

Stack Overflow用户

发布于 2011-06-17 08:13:20

这可能是资源加载顺序的问题.尝试分配层次结构中较低的元素的DataContext,例如用户控件下面的网格。

代码语言:javascript
复制
<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的属性部分中的数据绑定来设置绑定并确认您看到了定位器。选择DataContext应该去的元素,找到DataContext属性,然后单击属性值区域。现在应该打开一个对话框,您可以在其中选择定位器。这可能解决了问题,或者帮助你找到了解决之道。还可以在绑定之前重新构建项目。

票数 2
EN

Stack Overflow用户

发布于 2011-06-18 12:35:13

验证您的ViewModels中没有抛出异常。通常,当我收到该错误时,无法实例化定位器,因为上游视图模型构建之一会引发异常。你能张贴你的定位器构造函数吗?

如果您想自己动手解决这个问题,请在CreateVM中的第一个VMLocator语句上放置一个断点,看看哪个VM抛出了异常。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6329033

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档