我已经尝试了几个小时才能达到可以启动WPF应用程序并完全控制的程度。我希望能够创建一个ViewModel,创建一个View(Window),将View的数据上下文设置为ViewModel,然后显示View。
我尝试了很多方法,最有希望的是将App.xaml更改为页面,然后添加我自己的Main方法。不幸的是,这不能正常工作,因为VS2010不会在设计器中显示来自App.xaml的样式,尽管它们在运行应用程序时可以正常工作。
有没有办法做我想要的?如果没有,人们通常如何在WPF中启动MVVM应用程序,在View本身之外创建一个ViewModel?
答案 0 :(得分:23)
我会使用Startup事件。您可以将其添加到App.xaml并删除StartupUri行。添加它时,Visual Studio可以在App.xaml.cs文件中为您创建事件。您可以在其中初始化ViewModel和View。
答案 1 :(得分:21)
这是一个简单的方法......
<Application
x:Class="Demo.Ux.WpfApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
</Application>
这是基本的App.xaml.cs
public partial class App
{
protected override void OnStartup(StartupEventArgs e)
{
try
{
var mainView = new MainView();
mainView.Show();
mainView.DataContext = new MainViewModel();
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
}
}
Application.MainWindow
也可以使用。第一个显示的窗口将自动神奇地分配给MainWindow。当然,您可以跳过创建mainView
并直接写入MainWindow
,这也会减少语法。
MainWindow = new MainView();
MainWindow.Show();
MainWindow.DataContext = new MainViewModel();
最后一点,我在数据绑定之前正在进行Show
。您需要这样做以避免MainViewModel
在创建期间抛出异常的情况。如果尚未显示MainView
,则应用会关闭但不会让您看到错误。
答案 2 :(得分:2)
在我们的应用程序中,我们选择了您已经提出的方法:编写一个新的Main方法。您还必须在项目应用程序设置中进行一些更改(无启动对象)。应用程序xaml必须看起来像这样:
<Application x:Class="EVOCURA.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="Application_Startup"
Exit="Application_Exit">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!--Custom Controls-->
<ResourceDictionary Source="<your resources here>"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
后面的代码看起来像这样:
public sealed partial class App : Application
{
static App()
{ }
public App()
{ }
private void Application_Startup(object sender, StartupEventArgs e)
{
// create the main window and assign your datacontext
MainAppWindow main = new MainAppWindow();
main.DataContext = <your datacontext here>
main.Show();
}
[STAThreadAttribute]
public static int Main(string[] args)
{
App app = new App();
app.InitializeComponent();
app.Run();
return 0;
}
}
查看启动事件并注意,在App.xaml中没有指定默认的StartupUri
您也可以在MainWindow的新构造函数中传递DataContext,或者直接在xaml中创建DataContext。
答案 3 :(得分:1)
将ViewModel实例分配给视图的DataContext的最简单方法是在Window后面的代码中。
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new myViewModel();
}
}
对于问题的第一部分,您可以在StartUp事件中拥有应用程序的控件
<Application x:Class="myApplication.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml" Startup="Application_Startup">
<Application.Resources>
</Application.Resources>
</Application>
代码背后:
public partial class App : Application
{
private void Application_Startup(object sender, StartupEventArgs e)
{
// Place your code here
}
}