WindowStartupLocation CenterOwner仅在Visual Studio中工作

时间:2019-05-15 08:53:51

标签: c# wpf

我只是偶然发现了WPF应用程序中的一些奇怪行为。

我尝试确保某些窗口将与“父窗口”显示在同一屏幕上。

为此,我使用Window-Property WindowStartupLocation = CenterOwner,当直接从Visual Studio 运行时,该窗口可以正常运行。

奇怪的事情是,当我运行完全相同的.exe(... \ Project \ bin \ Debug \ Project.exe)“手动” 时,“子窗口”总是在我的主屏幕上启动,无论我是否移动了“父窗口”。

因此,当我将“父窗口”移到第二屏幕并打开“子窗口”时,它仍将显示在主屏幕上,而不是按预期方式显示在第二屏幕上。

所以我的问题是,如果运行.exe,我会得到不同的行为 “手动”或直接从Visual Studio。

我使用的ExtensionMethods:

public static class ExtensionMethods {
//I created these Extensions, to easily show Windows on the same screen, as a give Window.

    public static bool? ShowDialog(this Window child, Window owner) {
        child.WindowStartupLocation = WindowStartupLocation.CenterOwner;
        child.Owner = owner;
        return child.ShowDialog();
    }

    public static void Show(this Window child, Window owner) {
        child.WindowStartupLocation = WindowStartupLocation.CenterOwner;
        child.Owner = owner;
        child.Show();
    }
}

我如何打开新的“子窗口”

public void test(Window pw) {
    ChildWindow cw = new ChildWindow();
    cw.ShowDialog(pw); //Edited typo from "cw.ShowDialog(w);"
}



编辑:

我刚刚创建了一个新项目,其中只有两个Windows及其扩展方法,可以在干净的环境中试用它。

在此过程中,我发现只有在第二个窗口最大化时才会出现问题。既可以在xaml中设置WindowState = Maximized,也可以通过子窗口的构造方法中的代码设置。

仍然直接从Visual Studio中获得该行为,正如预期的那样,但在直接运行.exe时却没有。

“新”项目的完整代码:

MainWindow XAML:

<Window x:Class="WpfApplication3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Button Content="Open Child" Click="btn"/>
    </Grid>
</Window>

MainWindow CS:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication3 {
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window {
        public MainWindow() {
            InitializeComponent();
        }

        public void btn(object sender, RoutedEventArgs e) {
            test(this);
        }

        public void test(Window pw) {
            ChildWindow cw = new ChildWindow();
            cw.ShowDialog(pw);
        }
    }

    public static class ExtensionMethods {
        //I created these Extensions, to easily show Windows on the same screen, as a give Window.

        public static bool? ShowDialog(this Window child, Window owner) {
            child.WindowStartupLocation = WindowStartupLocation.CenterOwner;
            child.Owner = owner;
            return child.ShowDialog();
        }

        public static void Show(this Window child, Window owner) {
            child.WindowStartupLocation = WindowStartupLocation.CenterOwner;
            child.Owner = owner;
            child.Show();
        }
    }
}

ChildWindow XAML:

<Window x:Class="WpfApplication3.ChildWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ChildWindow" Height="300" Width="300"
        WindowState="Maximized">
    <Grid>
        <TextBlock Text="CHILD"/>
    </Grid>
</Window>

ChildWindow CS:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace WpfApplication3 {
    /// <summary>
    /// Interaktionslogik für ChildWindow.xaml
    /// </summary>
    public partial class ChildWindow : Window {
        public ChildWindow() {
            InitializeComponent();
        }
    }
}

1 个答案:

答案 0 :(得分:1)

我仍然不明白为什么会发生这种行为,但我仍然找到了解决方法。

该问题似乎与“最大化”现象有关。在VS中和直接执行WindowState时,如果不更改WindowState,则行为均符合预期。

我的解决方法是,在加载窗口后最大化窗口,因为那样就可以在正确的屏幕上显示

子窗口构造器中的示例代码:

public ChildWindow() {
    InitializeComponent();

    this.Loaded += delegate(object ds, RoutedEventArgs de) {
        ((Window)ds).WindowState = System.Windows.WindowState.Maximized;
    };
}

如果有人偶然发现了这个问题,并且还有一些有关为什么会出现此问题的更多信息,请随时分享。

对于我来说,这是一个小麻烦,但是它可以正常工作,所以我现在就解决。



编辑:

对于所有感兴趣的人,为了减少不便,我对我的ExtensionMethod进行了一些改动:

public static bool? ShowDialog(this Window child, Window owner) {
    child.WindowStartupLocation = WindowStartupLocation.CenterOwner;
    child.Owner = owner;

    //Detects, if the Window should be Maximized. If so set the State to
    //Normal instead and add an Eventhandler to Maximize the Window after beeing loaded.
    if (child.WindowState == WindowState.Maximized) {
        child.WindowState = WindowState.Normal;
        child.Loaded += delegate(object ds, RoutedEventArgs de) {
            ((Window)ds).WindowState = System.Windows.WindowState.Maximized;
        };
    }

    return child.ShowDialog();
}

这样,您可以照常在XMAL中设置WindowState,而无需自己在加载的事件中显式设置。

相关问题