เพิ่ม ViewModel ใหม่ให้กับ ViewModelLocator ใน MVVM Light Toolkit

ฉันรู้ว่าคำถามนี้ค่อนข้างพื้นฐาน แต่ในขณะนี้ ฉันสับสนไปหมดแล้วว่าควรเพิ่ม ViewModel ใหม่ให้กับคลาส ViewModelLocator ของฉันใน MVVM Light Toolkit ได้อย่างไร

การใช้งานปัจจุบันของฉันมีลักษณะดังนี้:

ขั้นแรกสมมติว่าฉันมีหน้าต่างชื่อ Settings, ViewModel ชื่อ SettingsViewModel และ ViewModelLocator ViewModelLocator

ก่อนอื่นฉันเรียก CreateSettings() ในตัวสร้าง VieModelLocator:

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

    }
    else
    {
        CreateSettings();
    }

    CreateMain();
}

โปรดทราบว่าสิ่งนี้จะทำงานเสมอเนื่องจากฉันไม่ได้ใช้การผสมผสานและสร้างแอปพลิเคชันทุกครั้งที่ฉันพยายามเรียกใช้ ตอนนี้สำหรับวิธีการ `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 ได้ แต่ส่วนใหญ่เกี่ยวข้องกับการผสมผสาน

แนวทางปัจจุบันของฉันคือฉันกำลังทำอะไรผิด แต่มีเอกสารเพียงเล็กน้อยในการเพิ่ม ViewModels ใหม่ ซึ่งฉันไม่แน่ใจว่าฉันทำอะไรผิด

แก้ไข:

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>

person DanteTheEgregore    schedule 31.07.2013    source แหล่งที่มา
comment
เฮ้ ดันเต้ สิ่งนี้ตอบคำถามของคุณหรือเปล่า? (หากใช่ คุณสามารถทำเครื่องหมายว่าตอบแล้ว หากไม่ใช่ คุณสามารถอธิบายรายละเอียดเพิ่มเติมได้ :)   -  person Noctis    schedule 27.11.2013


คำตอบ (2)


โดยปกติแล้วจะมีลักษณะดังนี้:

    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 (สมมติว่าคุณติดตั้ง mvvmlight ด้วย nuget แล้วเพิ่มโปรเจ็กต์ wvvm ใหม่

จากนั้นจะมี 2 กรณีสำหรับการออกแบบและรันไทม์ (หากคุณไม่ได้ใช้ คุณสามารถข้ามบิต if (IsInDesignMode) ... แล้วใส่ตรรกะของคุณลงไปได้ (แม้ว่าจะน่าเสียดายก็ตาม เนื่องจากเป็นการดีที่มีการดูตัวอย่างข้อมูลปลอมบางส่วนในตัวออกแบบ VS ...)

การเพิ่ม ViewModels ใหม่มักจะเกี่ยวข้องกับการสร้างคุณสมบัติประเภทนั้น และลงทะเบียนคุณสมบัติเหล่านั้นกับตัวระบุตำแหน่ง เพื่อให้คุณสามารถดึงข้อมูลมาได้ ... แต่สิ่งนี้แตกต่างและสามารถทำได้แตกต่างออกไป ฉันเชื่อว่า ...

หวังว่าสิ่งนี้จะช่วยได้ และหากมีสิ่งใดที่เราสามารถช่วยได้ โปรดแจ้งให้เราทราบ

person Noctis    schedule 26.09.2013

การเชื่อมโยงบริบทข้อมูลของคุณพยายามนำไปใช้เร็วกว่าที่มีการประกาศทรัพยากร ลองประกาศการเชื่อมโยงด้วยวิธีนี้ (แน่นอนว่าสิ่งนี้จะช่วยได้ก็ต่อเมื่อ 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>
person Dennis    schedule 31.07.2013
comment
ลองคำตอบของคุณแล้วและฉันยังคงได้รับข้อผิดพลาดเดียวกัน app.xaml ของฉันมีทรัพยากรตัวระบุตำแหน่ง ดูการแก้ไขที่ฉันทำด้านบน - person DanteTheEgregore; 31.07.2013
comment
ฉันจะรวมทรัพยากร Locator เข้ากับ MainSkin.xaml ได้อย่างไร - person DanteTheEgregore; 01.08.2013