33

Cancel 按钮背后的基本思想是启用 Escape Keypress 关闭窗口。

您可以将 Cancel 按钮上的 IsCancel 属性设置为 true,从而使 Cancel 按钮自动关闭对话框而不处理 Click 事件。

资料来源:Programming WPF (Griffith, Sells)

所以这应该有效

<Window>
<Button Name="btnCancel" IsCancel="True">_Close</Button>
</Window>

但是,我期望的行为对我不起作用。父窗口是由 Application.StartupUri 属性指定的主应用程序窗口。有效的是

<Button Name="btnCancel" IsCancel=True" Click="CloseWindow">_Close</Button>

private void CloseWindow(object sender, RoutedEventArgs) 
{
    this.Close();
}
  • IsCancel 的行为是否根据 Window 是普通窗口还是对话框而有所不同?IsCancel 是否仅在调用 ShowDialog 时才像宣传的那样工作?
  • 按钮(IsCancel 设置为 true)是否需要显式 Click 处理程序才能在 Escape 按下时关闭窗口?
4

4 回答 4

35

是的,它只适用于对话框,因为普通窗口没有“取消”的概念,它与 WinForms 中从 ShowDialog 返回的 DialogResult.Cancel 相同。

如果你想关闭一个带有转义的窗口,你可以在窗口上添加一个处理程序到 PreviewKeyDown,选择它是否是 Key.Escape 并关闭表单:

public MainWindow()
{
    InitializeComponent();

    this.PreviewKeyDown += new KeyEventHandler(CloseOnEscape);
}

private void CloseOnEscape(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Escape)
        Close();
}
于 2009-01-07T08:46:37.740 回答
17

我们可以将史蒂夫的回答更进一步,并创建一个附加属性,为任何窗口提供“关闭时转义”功能。编写一次属性并在任何窗口中使用它。只需将以下内容添加到窗口 XAML:

yournamespace:WindowService.EscapeClosesWindow="True"

这是该属性的代码:

using System.Windows;
using System.Windows.Input;

/// <summary>
/// Attached behavior that keeps the window on the screen
/// </summary>
public static class WindowService
{
   /// <summary>
   /// KeepOnScreen Attached Dependency Property
   /// </summary>
   public static readonly DependencyProperty EscapeClosesWindowProperty = DependencyProperty.RegisterAttached(
      "EscapeClosesWindow",
      typeof(bool),
      typeof(WindowService),
      new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnEscapeClosesWindowChanged)));

   /// <summary>
   /// Gets the EscapeClosesWindow property.  This dependency property 
   /// indicates whether or not the escape key closes the window.
   /// </summary>
   /// <param name="d"><see cref="DependencyObject"/> to get the property from</param>
   /// <returns>The value of the EscapeClosesWindow property</returns>
   public static bool GetEscapeClosesWindow(DependencyObject d)
   {
      return (bool)d.GetValue(EscapeClosesWindowProperty);
   }

   /// <summary>
   /// Sets the EscapeClosesWindow property.  This dependency property 
   /// indicates whether or not the escape key closes the window.
   /// </summary>
   /// <param name="d"><see cref="DependencyObject"/> to set the property on</param>
   /// <param name="value">value of the property</param>
   public static void SetEscapeClosesWindow(DependencyObject d, bool value)
   {
      d.SetValue(EscapeClosesWindowProperty, value);
   }

   /// <summary>
   /// Handles changes to the EscapeClosesWindow property.
   /// </summary>
   /// <param name="d"><see cref="DependencyObject"/> that fired the event</param>
   /// <param name="e">A <see cref="DependencyPropertyChangedEventArgs"/> that contains the event data.</param>
   private static void OnEscapeClosesWindowChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
   {
      Window target = (Window)d;
      if (target != null)
      {
         target.PreviewKeyDown += new System.Windows.Input.KeyEventHandler(Window_PreviewKeyDown);
      }
   }

   /// <summary>
   /// Handle the PreviewKeyDown event on the window
   /// </summary>
   /// <param name="sender">The source of the event.</param>
   /// <param name="e">A <see cref="KeyEventArgs"/> that contains the event data.</param>
   private static void Window_PreviewKeyDown(object sender, KeyEventArgs e)
   {
      Window target = (Window)sender;

      // If this is the escape key, close the window
      if (e.Key == Key.Escape)
         target.Close();
   }
}
于 2009-02-04T17:06:50.117 回答
6

这不太正确,不是吗... MSDN 说:当您将按钮的 IsCancel 属性设置为 true 时,您将创建一个向 AccessKeyManager 注册的 Button。然后,当用户按下 ESC 键时,该按钮被激活。因此,您的代码中确实需要一个处理程序并且您不需要任何附加属性或类似的东西

于 2011-12-01T01:22:16.150 回答
2

是的,这是正确的。在 WPF 中的 Windows 应用程序中,AcceptButton 和 Cancel 按钮在那里。但有一件事是,如果您将控件可见性设置为 false,那么它将无法按预期工作。为此,您需要在 WPF 中将可见性设置为 true。例如:(它不适用于取消按钮,因为这里的可见性是错误的)

<Button x:Name="btnClose" Content="Close" IsCancel="True" Click="btnClose_Click" Visibility="Hidden"></Button> 

所以,你需要做到:

<Button x:Name="btnClose" Content="Close" IsCancel="True" Click="btnClose_Click"></Button>

然后你btnClose_Click在文件后面写了代码:

private void btnClose_Click (object sender, RoutedEventArgs e)
    { this.Close(); }
于 2012-06-11T09:57:58.547 回答