Tambahkan ViewModel Baru ke ViewModelLocator di MVVM Light Toolkit

Saya tahu pertanyaan ini agak mendasar, tetapi saat ini, saya benar-benar bingung bagaimana cara menambahkan ViewModel baru ke kelas ViewModelLocator saya di MVVM Light Toolkit.

Implementasi saya saat ini terlihat seperti ini:

Pertama-tama asumsikan bahwa saya memiliki Window bernama Settings, ViewModel bernama SettingsViewModel dan ViewModelLocator ViewModelLocator.

Pertama saya memanggil CreateSettings() di konstruktor VieModelLocator:

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

    }
    else
    {
        CreateSettings();
    }

    CreateMain();
}

Perhatikan bahwa ini akan selalu berjalan karena saya tidak menggunakan campuran dan membangun aplikasi setiap kali saya mencoba menjalankannya. Sekarang untuk metode `CreateSettings().

Saya tidak tahu apa yang saya lakukan, jadi saya mencoba bermain aman dan memodelkan semuanya berdasarkan metode yang digunakan untuk membuat dan mengelola MainViewModel.

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

Kemudian beberapa metode lain yang meniru metode yang digunakan untuk 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;
    }
}

Dan di Settings Window Xaml saya:

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

Jendela kemudian dibuka dari MainViewModel saya seperti:

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

Jika saya mencoba ini, saya menerima pengecualian:

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

Dan pengecualian dalam:

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

Saya telah membaca tentang kesalahan yang melibatkan ketidakmampuan Window untuk menemukan sumber daya Locator, tetapi sebagian besar berkaitan dengan campuran.

Pendapat saya saat ini adalah bahwa saya melakukan sesuatu yang salah, tetapi hanya ada sedikit dokumentasi mengenai penambahan ViewModels baru sehingga saya tidak yakin apa kesalahan yang saya lakukan.

Sunting:

Aplikasi Saya.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>

person DanteTheEgregore    schedule 31.07.2013    source sumber
comment
Hai Dante, apakah ini menjawab pertanyaanmu? (jika ya, Anda dapat menandainya sebagai telah dijawab, jika tidak, Anda dapat menguraikannya lebih lanjut :)   -  person Noctis    schedule 27.11.2013


Jawaban (2)


Biasanya seperti ini tampilannya:

    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 itu statis, sepertinya milik Anda tidak. Biasanya berada di folder ViewModel (dengan asumsi Anda menginstal mvvmlight dengan nuget dan kemudian menambahkan proyek wvvm baru.

kemudian melanjutkan dengan memiliki 2 kasus untuk desain dan runtime. (jika Anda tidak menggunakannya, Anda dapat melewati bit if (IsInDesignMode) ..., dan memasukkan logika Anda saja. (walaupun sayang, karena menyenangkan untuk melihat pratinjau beberapa data palsu di VS designer ...)

Menambahkan ViewModels baru biasanya melibatkan pembuatan properti jenis itu, dan mendaftarkannya ke pencari lokasi, sehingga Anda kemudian dapat mengambilnya ... tetapi ini berbeda dan saya yakin dapat dilakukan secara berbeda ...

Semoga ini bisa membantu, dan jika ada hal lain yang bisa saya bantu, beri tahu saya.

person Noctis    schedule 26.09.2013

Pengikatan konteks data Anda mencoba diterapkan lebih awal, sebelum sumber daya dideklarasikan. Cobalah mendeklarasikan pengikatan dengan cara ini (tentu saja, ini hanya akan membantu jika MainSkin.xaml atau sumber daya aplikasi berisi sumber daya 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>
person Dennis    schedule 31.07.2013
comment
Mencoba jawaban Anda dan saya masih mendapatkan kesalahan yang sama. App.xaml saya berisi Sumber Daya Pencari Lokasi. Lihat hasil edit yang saya buat di atas. - person DanteTheEgregore; 31.07.2013
comment
Bagaimana cara mengintegrasikan sumber daya Locator ke MainSkin.xaml? - person DanteTheEgregore; 01.08.2013