2014-11-21 86 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