有没有一种方法可以在不使用 StartUpUri 的情况下启动 WPF 应用程序,并且不会破坏其他内容?

问题描述 投票:0回答:5

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

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

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

wpf mvvm
5个回答
27
投票

我会使用启动事件。您可以将其添加到 App.xaml 并删除 StartupUri 行。添加它后,Visual Studio 可以在 App.xaml.cs 文件中为您创建事件。您可以在其中初始化您的 ViewModel 和 View。


25
投票

这是一种简单的方法...

<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
也可以使用。 第一个显示的窗口将自动分配给主窗口。 当然,您可以跳过创建
mainView
并直接写入
MainWindow
,这也会简化语法。

 MainWindow = new MainView();
 MainWindow.Show();
 MainWindow.DataContext = new MainViewModel();

最后一点,我在数据绑定之前执行

Show
。您需要这样做以避免
MainViewModel
在创建过程中抛出异常。 如果尚未显示
MainView
,应用程序将关闭,而不会让您看到错误。


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。


1
投票

将 ViewModel 实例分配给视图的 DataContext 的最简单方法是在 Window 后面的代码中。

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        DataContext = new myViewModel();
    }
}

对于问题的第一部分,您可以在启动事件中拥有应用程序的control

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

0
投票

如果您将 MVVM 与 DI 结合使用(例如 CommunityToolkit),您可以使用如下内容:

/// <summary>Raises the <see cref="E:System.Windows.Application.Startup" /> event.</summary>
/// <param name="e">A <see cref="T:System.Windows.StartupEventArgs" /> that contains the event data.</param>
protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);

    var shell = Services.GetService<ShellWindow>();
    var shellViewModel = Services.GetService<ShellWindowViewModel>();
    shell!.Show(); // or you can check for null
    shell.DataContext = shellViewModel;
}
© www.soinside.com 2019 - 2024. All rights reserved.