【问题标题】:Add a New ViewModel to ViewModelLocator in MVVM Light Toolkit在 MVVM Light Toolkit 中向 ViewModelLocator 添加新的 ViewModel
【发布时间】:2013-07-31 18:27:14
【问题描述】:

我知道这个问题有点基础,但目前,我完全不知道如何在MVVM Light Toolkit 中将新的 ViewModel 添加到我的 ViewModelLocator 类中。

我当前的实现如下所示:

首先假设我有一个名为 Settings 的 Window、一个名为 SettingsViewModel 的 ViewModel 和一个 ViewModelLocator ViewModelLocator

首先我在 VieModelLocator 构造函数中调用CreateSettings()

public ViewModelLocator()
{
    if (ViewModelBase.IsInDesignModeStatic)
    {

    }
    else
    {
        CreateSettings();
    }

    CreateMain();
}

请注意,这将始终运行,因为我每次尝试运行它时都没有使用 blend 和构建应用程序。现在为 `CreateSettings() 方法。

我不知道自己在做什么,所以我尝试安全行事,并按照用于创建和管理 MainViewModel 的方法对所有内容进行建模。

public static void CreateSettings()
{
    if (_settings == null)
    {
        _settings = new SettingsViewModel();
    }
}

然后在 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;
    }
}

在我的Settings Window 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>

然后从我的 MainViewModel 打开窗口,如下所示:

Settings settings = new Settings();
settings.Show();

如果我尝试这个,我会收到一个异常:

"'Provide value on 'System.Windows.StaticResourceExtension' threw an exception.' Line number '4' and line position '39'."

还有一个内部例外:

"Cannot find resource named 'Locator'. Resource names are case sensitive."

我已经阅读了涉及 Window 无法找到 Locator 资源的错误,但大多数与混合有关。

我目前的看法是我做错了什么,但是关于添加新 ViewModel 的文档太少了,我不确定我做错了什么。

编辑:

我的 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>

【问题讨论】:

  • 嘿但丁,这回答了你的问题吗? (如果是,您可以将其标记为已回答,如果不是,您可以详细说明:)

标签: c# wpf xml xaml mvvm-light


【解决方案1】:

这是它通常的样子:

    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>();
        }
    }

    ...
}

ViewModelLocator 是静态的,您的似乎不是。它通常位于 ViewModel 文件夹中(假设您使用 nuget 安装了 mvvmlight,然后添加了一个新的 wvvm 项目。

然后它继续有 2 个案例用于设计和运行时。 (如果你不使用它,你可以跳过if (IsInDesignMode) ... 位,直接输入你的逻辑。(虽然很遗憾,因为在 VS 设计器中预览一些假数据真是太好了......)

添加新的 ViewModels 通常涉及创建该类型的属性,并将它们注册到定位器,这样您就可以检索它们......但这有所不同,我相信可以以不同的方式完成......

希望对您有所帮助,如果还有什么我可以帮忙的,请告诉我。

【讨论】:

    【解决方案2】:

    您的数据上下文绑定尝试在资源声明之前应用。尝试以这种方式声明绑定(当然,这只有在 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>
    

    【讨论】:

    • 试过你的答案,我仍然得到同样的错误。我的 app.xaml 包含一个定位器资源。请参阅我在顶部所做的编辑。
    • 如何将定位器资源集成到 MainSkin.xaml 中?
    猜你喜欢
    • 1970-01-01
    • 2016-06-21
    • 2014-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-19
    相关资源
    最近更新 更多