【问题标题】:Get reference to MainWindow in custom main() in WPF在 WPF 中的自定义 main() 中获取对 MainWindow 的引用
【发布时间】:2015-12-19 21:55:58
【问题描述】:

我正在尝试为我的 WPF 应用程序编写自定义 Main() 函数,以便我可以解析命令行并基于命令行配置 GUI。我不知道如何获得对Main() 的默认实现创建的MainWindow 实例的引用。在App.g.cs 中找到的自动生成的实现如下:

public void InitializeComponent() {
    if (_contentLoaded) {
        return;
    }
    _contentLoaded = true;

    #line 5 "..\..\..\App.xaml"
    this.StartupUri = new System.Uri("MainWindow.xaml", System.UriKind.Relative);

    #line default
    #line hidden
    System.Uri resourceLocater = new System.Uri("/MyApplication;component/app.xaml", System.UriKind.Relative);

    #line 1 "..\..\..\App.xaml"
    System.Windows.Application.LoadComponent(this, resourceLocater);

    #line default
    #line hidden
}

[System.STAThreadAttribute()]
public static void Main() {
    MyApplication.App app = new MyApplication.App();
    app.InitializeComponent();
    app.Run();
}

我遇到的问题是在实例化后尝试获取对我的MainWindow 类的引用(但这实际上是通过StartupUri 完成的)。我希望能够执行以下操作:

[System.STAThreadAttribute()]
public static void Main() {
    MyApplication.App app = new MyApplication.App();
    app.InitializeComponent();
    MyApplication.MainWindow w = (MyApplication.MainWindow)app.MainWindow;
    w.MyProgramIsAwesomeProperty = true;
    app.Run();
}

但是,app.MainWindow 始终是 null。我还尝试了以下方法并在 Console.WriteLine 行上设置断点,但程序永远不会到达这些回调:

[System.STAThreadAttribute()]
public static void Main() {
    MyApplication.App app = new MyApplication.App();
    app.LoadCompleted += app_LoadCompleted;
    app.Activated += app_Activated;
    app.InitializeComponent();
    app.Run();
}

static void app_Activated(object sender, EventArgs e)
{
    Console.WriteLine("Activated");
}

static void app_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
    Console.WriteLine("LoadCompleted");
}

那么,在我的 Main 函数中实例化 MyApplication.MainWindow 之后,如何获得对它的引用?

【问题讨论】:

  • 试试 Application.Current.MainWindow
  • 那也是null。 :-(
  • 我认为这是因为您需要创建一个 MainWindow 的实例,然后将其分配给 Application.Current.MainWindow

标签: c# wpf main


【解决方案1】:

如果你想从命令行向 GUI 发送一些东西,你最好在你的 Application 类中调用一个方法并从中打开你的 GUI。

打开您的 App.xaml 文件,从 Application 元素中删除 StartupUri 属性,然后添加 Startup 属性:

Startup="Application_Startup"

然后在您的 Application 类中创建一个 Application_Startup 方法,该方法读取命令行或其他内容并将其发送到您的 GUI:

private void Application_Startup(object sender, StartupEventArgs e)
{
    // e.Args contains command-line arguments.
    MainWindow mw = new MainWindow(Whatever(e.Args));
    mw.Show();
}

【讨论】:

  • 有理由使用这个 vs 覆盖 OnStartup( StartupEventArgs e ) 吗?
  • 那么,这个答案基本上是在做StartupUri 的东西吗?
  • @clcto 我记得很久以前没有调用OnStartup 的情况,但不记得原因是什么。是的,这基本上做了StartupUri 所做的事情,但是在创建主窗口之前做,所以你可以在它打开之前做一些事情,比如改变 GUI,甚至决定不显示 GUI。
  • 我刚刚尝试覆盖 OnStartup 并且效果很好,但我将把这个答案作为替代方法。
【解决方案2】:

其实StartupUri的设置并没有实例化主窗口,也没有设置对应的Application.MainWindow属性。这发生在稍后,在调用Run 方法之后,这就是你得到null 的原因。

正确的方法是避免StartupUri 并覆盖OnStartup 方法(虽然您可以按照建议添加事件处理程序,但在派生类中没有多大意义)。然后在OnStartup中,你可以直接实例化主窗口,设置你要设置的属性。

【讨论】:

    猜你喜欢
    • 2021-04-28
    • 2023-03-08
    • 2016-09-10
    • 1970-01-01
    • 1970-01-01
    • 2021-08-28
    • 1970-01-01
    • 2012-01-27
    • 1970-01-01
    相关资源
    最近更新 更多