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