我只是偶然发现了WPF应用程序中的一些奇怪行为。
我试图确保某些窗口将与它们的“父窗口”显示在同一屏幕上。
为此,我使用Window-Property WindowStartupLocation = CenterOwner
,当直接从Visual Studio运行时,它的功能与预期的一样。
奇怪的是,当我“手动”运行完全相同的.exe(... \ Project \ bin \ Debug \ Project.exe)时,无论如何,“ Child-Window”总是在主屏幕上启动如果我移动了“父窗口”。
因此,当我将“父窗口”移至第二屏幕并打开“子窗口”时,它仍将显示在主屏幕上,而不是按预期方式显示在第二屏幕上。
所以我的问题是,如果我手动或直接从Visual Studio运行.exe,我会得到不同的行为。
我使用的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及其扩展方法,可以在干净的环境中进行尝试。
在此过程中,我发现只有在第二个窗口最大化时才会出现问题。既可以WindowState = Maximized
在xaml中设置,也可以通过子窗口的构造函数上的代码设置。
仍然可以直接从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();
}
}
}
我仍然不明白为什么会发生这种现象,我仍然找到了解决方法。
该问题似乎与“ Child-Window”蜂拥而至。当不更改WindowState时,无论是在VS中还是直接执行时,其行为均符合预期。
我的解决方法是,在加载窗口后最大化窗口,因为那样就可以正确显示屏幕。
子窗口构造器中的示例代码:
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,而无需自己在加载的事件中显式设置。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句