我有一个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>
如果我的视图模型 ( 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"
首先,WPF 中的"Application"类应该用于一件事,而且只用于一件事:启动程序。它不是一个模型。
也就是说,我只会按顺序传递所有内容(这也适用于适当的模型):
MyViewModel viewmodel = new MyViewModel(this);
var app = new System.Windows.Application();
app.Run(new ApplicationShellView(viewmodel));
当然,请从 XAML 中删除数据上下文集。这确实需要修改代码隐藏以接受 VM 对象并将其设置为构造函数中的 DataContext,但这是将 VM 传递到视图的标准方法。
您还可以使用服务定位器来查找模型,或通过其他多种方式查找模型。不幸的是,很难说哪一个是正确的,因为你的模型太奇怪了。
顺便说一句,程序的标题在很大程度上是视图的一部分,可能根本不需要绑定(你的名字是静态的,所以让你的应用程序类成为模型不会给你带来任何东西)。