2014-11-21 128 views
0

我有一個HelloWorldWPFApplication級以下方法:如何設置模型在模型(MVVM)

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> 

如果我的視圖模型(ApplicationShellViewModel )具有以下方法,該窗口將標題設置爲「測試」:

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'

+0

所以澄清; 'ApplicationShellViewModel'有一個'Application'屬性,它是'WpfApplicationBase '的一個實例,它有一個'WindowTitle'屬性? – Unflux 2014-11-21 17:02:30

+0

ApplicationShellViewModel具有WindowTitle屬性,您說的所有內容都是正確的 – camelCase 2014-11-21 17:10:06

回答

1

首先,WPF中的「Application」類應該用於一件事情,並且只有一件事:啓動程序。它是而不是的一個模型。

這就是說,我只想通過在所有序列(這個可以申請到一個適當的模型以及):

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

當然,刪除X​​AML設置數據上下文。這確實需要修改後面的代碼來接受VM對象,並將其設置爲構造函數中的DataContext,但這是將VM傳遞給View的標準方式。

您也可以使用服務定位器來查找您的模型或許多其他方法。不幸的是,很難說哪一個是正確的,因爲你的模型是如此奇怪

作爲一個完全拋開;你的程序的標題是View的一部分,可能根本不需要綁定(你的名字是靜態的,所以讓你的應用程序類成爲模型並不會購買任何東西)。

+0

關於第一點,是的,我從一開始就理解了這一點。我的模型是一些特定於應用程序的數據(在這一點上,應用程序的名稱和版本號)。確保應用程序名稱對於單個項目是靜態的,但我試圖從項目的程序集屬性中自動化標題和版本號(因此會根據具體應用程序和構建的版本與我的framework.dll進行更改)。 – camelCase 2014-11-21 17:59:02

+0

@rasteve所以你的視圖模型(或實際模型)去得到它。我仍然不會使用「應用程序」作爲模型類。無論如何,我的答案仍然存在。我只是想提供一些一般性建議。 – BradleyDotNET 2014-11-21 18:03:10

+0

我的HelloWorldWPFApplication類是處理一些高級方法(運行,關閉等)的業務邏輯類。它包含一個類型爲HelloWorldWPFApplicationData的Data屬性,該屬性當前存儲特定於應用程序的數據。我的視圖模型需要這些屬性中的2個來制定窗口標題。我不確定是否可以將現有對象用作MVVM中的模型,或者我應該使用2個屬性創建合適的模型。 – camelCase 2014-11-21 18:03:59