简体   繁体   English

WPF Button.IsCancel属性如何工作?

[英]How does the WPF Button.IsCancel property work?

The basic idea behind a Cancel button is to enable closing your window with an Escape Keypress. “取消”按钮背后的基本思想是使用Escape Keypress关闭窗口。

You can set the IsCancel property on the Cancel button to true, causing the Cancel button to automatically close the dialog without handling the Click event. 您可以将“取消”按钮上的IsCancel属性设置为true,从而使“取消”按钮自动关闭对话框而不处理Click事件。

Source: Programming WPF (Griffith, Sells) 资料来源:编程WPF(格里菲斯,卖出)

So this should work 所以这应该工作

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

However the behavior I expect isn't working out for me. 然而,我期望的行为并不适合我。 The parent window is the main application window specified by the Application.StartupUri property. 父窗口是Application.StartupUri属性指定的主应用程序窗口。 What works is 有效的是

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

private void CloseWindow(object sender, RoutedEventArgs) 
{
    this.Close();
}
  • Is the behavior of IsCancel different based on whether the Window is a normal window or a Dialog? 根据窗口是普通窗口还是对话框,IsCancel的行为是否不同? Does IsCancel work as advertised only if ShowDialog has been called? 只有在调用ShowDialog时,IsCancel才能像宣传的那样工作吗?
  • Is an explicit Click handler required for the button (with IsCancel set to true) to close a window on an Escape press? 按钮是否需要显式的Click处理程序(IsCancel设置为true)以关闭Escape印刷机上的窗口?

Yes, it only works on dialogs as a normal window has no concept of "cancelling", it's the same as DialogResult.Cancel returning from ShowDialog in WinForms. 是的,它只适用于对话框,因为普通窗口没有“取消”的概念,它与从WinForms中的ShowDialog返回的DialogResult.Cancel相同。

If you wanted to close a Window with escape you could add a handler to PreviewKeyDown on the window, pickup on whether it is Key.Escape and close the form: 如果你想关闭一个带有转义的Window,你可以在窗口上为PreviewKeyDown添加一个处理程序,拾取它是否是Key.Escape并关闭表单:

public MainWindow()
{
    InitializeComponent();

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

private void CloseOnEscape(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Escape)
        Close();
}

We can take Steve's answer one step further and create an attached property that provides the "escape on close" functionality for any window. 我们可以进一步采取史蒂夫的答案并创建一个附加属性,为任何窗口提供“关闭时逃逸”功能。 Write the property once and use it in any window. 写一次属性并在任何窗口中使用它。 Just add the following to the window XAML: 只需将以下内容添加到窗口XAML:

yournamespace:WindowService.EscapeClosesWindow="True"

Here's the code for the property: 这是该属性的代码:

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();
   }
}

This isn't quite right is it... MSDN says this: When you set the IsCancel property of a button to true, you create a Button that is registered with the AccessKeyManager. 这是不对的... MSDN说:当您将按钮的IsCancel属性设置为true时,您将创建一个使用AccessKeyManager注册的Button。 The button is then activated when a user presses the ESC key. 然后,当用户按下ESC键时,该按钮被激活。 So you do need a handler in your code behind And you don't need any attached properties or anything like that 因此,您需要在代码中使用处理程序而且您不需要任何附加属性或类似的东西

Yes this is right.In windows Application in WPF AcceptButton and Cancel Button is there. 是的,这是正确的。在WPF中的Windows应用程序中,AcceptButton和Cancel Button就在那里。 But one thing is that if you are setting your control visibility as false, then it won't work as expected.For that you need to make as visibility as true in WPF. 但有一点是,如果您将控件可见性设置为false,则它将无法按预期工作。为此,您需要在WPF中将可见性视为true。 For example: (it is not working for Cancel button because here visibility is false) 例如:(它不适用于取消按钮,因为此处可见性为假)

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

So, you need make it: 所以,你需要做到:

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

Then you have write btnClose_Click in code behind file: 然后你在文件后面的代码中写了btnClose_Click

private void btnClose_Click (object sender, RoutedEventArgs e)
    { this.Close(); }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM