【问题标题】:How does the WPF Button.IsCancel property work?WPF Button.IsCancel 属性如何工作?
【发布时间】:2010-09-29 23:52:27
【问题描述】:

取消按钮背后的基本思想是启用退出键关闭窗口。

您可以将 IsCancel 属性设置为 取消按钮为真,导致 取消按钮自动关闭 不处理 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 是普通窗口还是 Dialog 而有所不同? IsCancel 是否仅在调用 ShowDialog 时才能像宣传的那样工作?
  • 按钮(IsCancel 设置为 true)是否需要显式 Click 处理程序才能在 Escape 按下时关闭窗口?

【问题讨论】:

    标签: wpf button


    【解决方案1】:

    是的,它只适用于对话框,因为普通窗口没有“取消”的概念,它与 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();
    }
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 是的。附加的属性仍然不会立即在我的脑海中“点击”。
      • 效果很好,唯一的事情是我必须将转换替换为 Window 并按照此处的建议添加一个 null 检查 - stackoverflow.com/questions/10206742/…,以避免错误“无法转换类型为 'Microsoft .Expression.Platform.WPF.InstanceBuilders.WindowInstance' 输入'System.Windows.Window'”(项目能够成功构建,但错误很烦人。那是我的VS 2012 + R#。我也必须在之后重新启动VS那个。
      【解决方案3】:

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

      【讨论】:

      【解决方案4】:

      是的,这是正确的。在 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(); }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-10-20
        • 1970-01-01
        • 2011-02-10
        • 2011-07-10
        • 2012-04-22
        • 1970-01-01
        • 1970-01-01
        • 2012-04-26
        相关资源
        最近更新 更多