簡體   English   中英

如何在視圖模型(MVVM)中設置模型

[英]How to set the model in a viewmodel (MVVM)

我有一個具有以下方法的HelloWorldWPFApplication類:

public override void Run()
{
    var app = new System.Windows.Application();
    app.Run(new ApplicationShellView());
}

ApplicationShellView具有以下XAML:

<winbase:ApplicationShell x:Class="HelloWorldWPFApplication.View.ApplicationShellView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:winbase="clr-namespace:Framework.Presentation.Control.Window;assembly=Framework"
    xmlns:vm="clr-namespace:HelloWorldWPFApplication.ViewModel"
    Title="{Binding WindowTitle, Mode=OneWay}">

<Window.DataContext>
    <vm:ApplicationShellViewModel  />
</Window.DataContext>

</winbase:ApplicationShell>

如果我的ViewModel( ApplicationShellViewModel )具有以下方法,則窗口的標題將設置為“ Test”:

    public string WindowTitle
    {
        get
        {
            return "Test";
        }
    }

我的問題是我想根據HelloWorldWPFApplication類中的屬性設置標題。 我將以下內容添加到HelloWorldWPFApplication的基類(使用INotifyPropertyChanged接口):

private WpfApplicationBase<WpfApplicationDataBase> applicationModel;

public WpfApplicationBase<WpfApplicationDataBase> Application
{
    get { return this.applicationModel; }
    set { this.Set<WpfApplicationBase<WpfApplicationDataBase>>(ref this.applicationModel, value); }
}

如此有效,我計划將現有的HelloWorldWPFApplication對象作為模型重用(在MVVM中)。

我將WindowTitle屬性更改如下:

public string WindowTitle
{
    get
    {
        return String.Format("{0} {1}",
              this.applicationModel.Data.FullName,
              this.applicationModel.Data.ReleaseVersion).Trim();
    }
}

當然,由於尚未設置應用程序字段,因此在此階段我的項目將創建一個沒有標題的窗口。 我不想在視圖模型中創建一個新的應用程序對象,因為它已經存在。 我想使用這個現有對象。 實現此目標的最佳方法是什么?

我對MVVM / WPF非常陌生-從對MVVM的基本了解,我不想在視圖中放任何代碼。 我可以在靜態類上為應用程序對象設置一個靜態字段,然后在我的視圖模型中分配此字段(此方法有效,但不確定具有“全局”變量是最佳方法)。

我還嘗試過在顯示窗口之前創建視圖模型,但是遇到了尚未解決的問題。 在此實現中,我的run方法如下所示:

public override void Run()
{
    var window = new ApplicationShell();  // inherits from System.Windows.Window
    var vm = new ApplicationShellViewModel();
    vm.Application = this;  // this line won't compile
    window.DataContext = vm;

    this.Data.WpfApplication.Run(window);
}

我收到一個編譯錯誤:

錯誤1無法將類型'HelloWorldWPFApplication.Program.HelloWorldApplication'隱式轉換為'Framework.Business.Logic.Program.Application.WpfApplicationBase'

我對錯誤感到困惑,因為我的HelloWorldWPFApplication類繼承自WpfApplicationBase

    public class HelloWorldApplication<T> : WpfApplicationBase<T>
    where T : HelloWorldApplicationData

此外,HelloWorldApplicationData繼承自WpfApplicationDataBase。

我通過以下實現得到了幾乎相同的問題:

public override void Run()
{
    var window = new ApplicationShell();
    var vm = new ApplicationShellViewModel();
    var app = new HelloWorldApplication<HelloWorldApplicationData>();
    vm.Application = app;  // Cannot implicitly convert type error again
    window.DataContext = vm;

    this.Data.WpfApplication.Run(window);
}

確切錯誤:

錯誤1無法將類型'HelloWorldWPFApplication.Program.HelloWorldApplication'隱式轉換為'Framework.Business.Logic.Program.Application.WpfApplicationBase'

首先,應該將WPF中的“ Application”類用於一件事,並且只能用於一件事: 啟動程序 不是模型。

就是說,我將按順序傳遞所有內容(這也適用於適當的模型):

MyViewModel viewmodel = new MyViewModel(this);
var app = new System.Windows.Application();
app.Run(new ApplicationShellView(viewmodel));

當然,請從XAML中刪除數據上下文集。 這確實需要修改后面的代碼以接受VM對象並將其設置為構造函數中的DataContext,但這就是將VM傳遞給View的一種標准方法。

您還可以使用“服務定位器”來找到您的模型,或者使用其他多種方式。 不幸的是,由於您的模型太奇怪了 ,很難說哪個是對的。

作為補充; 程序的標題幾乎是View的一部分,可能根本不需要綁定(您的名稱是靜態的,因此使您的應用程序類成為模型並不會為您帶來任何收益)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM