有没有办法在没有StartUpUri的情况下启动WPF应用程序而不破坏别的东西?

时间:2010-08-09 10:57:21

标签: wpf mvvm

我已经尝试了几个小时才能达到可以启动WPF应用程序并完全控制的程度。我希望能够创建一个ViewModel,创建一个View(Window),将View的数据上下文设置为ViewModel,然后显示View。

我尝试了很多方法,最有希望的是将App.xaml更改为页面,然后添加我自己的Main方法。不幸的是,这不能正常工作,因为VS2010不会在设计器中显示来自App.xaml的样式,尽管它们在运行应用程序时可以正常工作。

有没有办法做我想要的?如果没有,人们通常如何在WPF中启动MVVM应用程序,在View本身之外创建一个ViewModel?

4 个答案:

答案 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
    }
}