我想在我的wpf项目中关闭窗口,当用户点击escape按钮时。我不想在每个窗口中编写代码,而是想创建一个类,可以捕获用户按下escape键的事件。
我想在我的wpf项目中关闭窗口,当用户点击escape按钮时。我不想在每个窗口中编写代码,而是想创建一个类,可以捕获用户按下escape键的事件。
选项1
使用Button.IsCancel属性。
<Button Name="btnCancel" IsCancel="true" Click="OnClickCancel">Cancel</Button>
当你将按钮的IsCancel属性设置为true时,你创建了一个已向AccessKeyManager注册的按钮。当用户按ESC键时,该按钮会被激活。
然而,这只对对话框有效。
选项2
如果你想要在按下Esc键时关闭窗口,可以在窗口上添加PreviewKeyDown的处理程序。
public MainWindow()
{
InitializeComponent();
this.PreviewKeyDown += new KeyEventHandler(HandleEsc);
}
private void HandleEsc(object sender, KeyEventArgs e)
{
if (e.Key == Key.Escape)
Close();
}
这是一个无需按钮的解决方案,简洁并更符合MVVM思想。将以下XAML添加到您的对话框/窗口中:
<Window.InputBindings>
<KeyBinding Command="ApplicationCommands.Close" Key="Esc" />
</Window.InputBindings>
<Window.CommandBindings>
<CommandBinding Command="ApplicationCommands.Close" Executed="CloseCommandBinding_Executed" />
</Window.CommandBindings>
并在代码后台处理该事件:
private void CloseCommandBinding_Executed(object sender, System.Windows.Input.ExecutedRoutedEventArgs e)
{
if (MessageBox.Show("Close?", "Close", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
this.Close();
}
PreviewKeyDown += (s,e) => { if (e.Key == Key.Escape) Close() ;};
InputBinding
选项非常好用且灵活。Preview
事件发生得非常早。如果你有一个嵌套控件应该为自己的目的使用Esc键,那么在窗口级别夺取它可能会破坏该控件的功能。protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (!e.Handled && e.Key == Key.Escape && Keyboard.Modifiers == ModifierKeys.None)
{
this.Close();
}
}
using System.Windows;
using System.Windows.Input;
public static class WindowUtilities
{
/// <summary>
/// Property to allow closing window on Esc key.
/// </summary>
public static readonly DependencyProperty CloseOnEscapeProperty = DependencyProperty.RegisterAttached(
"CloseOnEscape",
typeof(bool),
typeof(WindowUtilities),
new FrameworkPropertyMetadata(false, CloseOnEscapeChanged));
public static bool GetCloseOnEscape(DependencyObject d)
{
return (bool)d.GetValue(CloseOnEscapeProperty);
}
public static void SetCloseOnEscape(DependencyObject d, bool value)
{
d.SetValue(CloseOnEscapeProperty, value);
}
private static void CloseOnEscapeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is Window target)
{
if ((bool)e.NewValue)
{
target.PreviewKeyDown += Window_PreviewKeyDown;
}
else
{
target.PreviewKeyDown -= Window_PreviewKeyDown;
}
}
}
private static void Window_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (sender is Window target)
{
if (e.Key == Key.Escape)
{
target.Close();
}
}
}
}
And use it your windows' XAML like this:
<Window ...
xmlns:custom="clr-namespace:WhereverThePropertyIsDefined"
custom:WindowUtilities.CloseOnEscape="True"
...>
添加一个IsCancel="True"的按钮,但宽度和高度为0(用于隐藏)
<Button Width="0" Height="0" IsCancel="True"/>