【发布时间】:2017-12-21 18:14:38
【问题描述】:
我在 .NET 4.7 中有一个简单的 WPF 应用程序。主窗口监听“Key Up”事件。如果按下 Escape 键,主窗口会自行关闭。这工作正常(至少它开始工作正常)。
主窗口还包含一个打开另一个窗口的按钮(称为 X)。 X 只是一个空的窗口。它没有事件处理程序。当 X 打开时,主窗口中的按钮被禁用。一旦 X 关闭,按钮就会重新启用。
问题是:一旦 X 关闭,主窗口的 Key Up 事件处理程序似乎就消失了……有点。我不能再按 Escape 来关闭主窗口除非我首先将焦点放在其中一个按钮上。如果我只是单击主窗口并按 Escape,它不会关闭窗口。在展示 Window X 之前,情况并非如此。
事实证明,如果我不禁用并重新启用按钮,则 Key Up 事件处理程序在 X 关闭后继续工作——我仍然可以通过按下来可靠地关闭主窗口退出键。
显然,我是 WPF 的新手。我想知道 Windows 事件是否发生了一些奇怪的事情。
这是主窗口的 XAML,后面是它的代码。我还包含了 Window X 的 XAML 和代码(顺便说一句,Window X 是 WrapPanelWindow)。
<Window x:Class="Wpf_01.MainWindow" x:ClassModifier="internal"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Wpf_01"
mc:Ignorable="d"
Title="Main Window" Height="300" Width="300" Background="#FF6289A4" KeyUp="Key_Up">
<StackPanel Margin="20,10,20,10">
<Button Content="Canvas Example"/>
<Button Content="WrapPanel Example" Click="Button_Click"/>
<Button Content="DockPanel Example"/>
<Button Content="Grid Example"/>
<Button Content="StackPanel Example"/>
</StackPanel>
下面是主窗口的代码:
namespace Wpf_01 {
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
internal partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e) {
Button clickedButton = sender as Button;
Window newWindow = null;
switch(clickedButton.Content) {
case "Canvas Example":
newWindow = new CanvasWindow();
break;
case "WrapPanel Example":
newWindow = new WrapPanelWindow();
break;
}
if(newWindow != null) {
clickedButton.IsEnabled = false;
newWindow.Show();
newWindow.Closed += (x, y) => clickedButton.IsEnabled = true;
}
} // Button_Clicked()
private void Key_Up(object sender, KeyEventArgs e) {
if(e.Key == Key.Escape)
Close();
} // KeyHandler()
}
}
这里是 WrapPanelWindow XAML 和后面的代码:
<Window x:Class="Wpf_01.WrapPanelWindow" x:ClassModifier="internal"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Wpf_01"
mc:Ignorable="d"
Title="Fun with WrapPanel Window" Height="200" Width="260">
<Grid>
</Grid>
</Window>
最后是 WrapPanelWindow 的代码。
namespace Wpf_01 {
/// <summary>
/// Interaction logic for WrapPanelWindow.xaml
/// </summary>
internal partial class WrapPanelWindow : Window {
public WrapPanelWindow() {
InitializeComponent();
}
}
}
【问题讨论】:
-
我刚刚测试了你的代码,它运行良好。我怀疑还有更多代码。如果是这样,请发布它。如果有任何与这些事件相关的 XAML 也会发布。如果我们无法重现,我们将无法回答您的问题
-
添加的代码看起来不错。确保清理解决方案(在解决方案资源管理器中右键单击解决方案)并重建它。在 Key_Up 方法中设置断点 (F9) 以查看它是否被调用。
-
@Erno - 断点不会被击中。 X 关闭后,我可以将焦点放回其中一个按钮上,Escape 键将关闭主窗口。但如果焦点在主窗口本身,它就不起作用。
-
几点说明: 1. 在我的机器上,如果窗口有焦点,它确实可以工作。 2. 如果用户打开多个窗口,此设置将不会缩放(一旦关闭退出按钮再次启用) 3. 更好的解决方案是将所有打开的窗口添加到列表中,并且仅在以下情况下关闭窗口/应用程序列表为空。 (不要忘记从列表中删除关闭的窗口)
-
@Erno:奇怪的是它对你有用。就我而言,一旦 Window X 关闭,特定的 Button 需要在 Escape 关闭 Window 之前获得焦点。例如,我不能简单地单击窗口的标题栏并按 Escape。
标签: wpf