我只是偶然发现了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();
}
}
}
答案 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,而无需自己在加载的事件中显式设置。