2009-01-07 84 views
31

“取消”按钮背后的基本思想是通过Escape Keypress启用关闭窗口。WPF Button.IsCancel属性如何工作?

可以取消按钮设置IsCancel属性上 为true,导致 取消按钮自动关闭 对话框不处理点击 事件。

来源:编程WPF(格里菲斯,销售)

所以这应该工作

<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不同的基于窗口是否是一个正常的窗口或对话框中的行为吗?只有在ShowDialog被调用后,IsCancel才能像广告一样工作吗?
  • 该按钮是否需要一个明确的Click处理程序(IsCancel设置为true)来关闭Escape按钮上的窗口?

回答

29

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

如果你想关闭一个窗口逃生,你可以在它是否是一个Key.Escape处理程序添加到PreviewKeyDown在窗口上,皮卡和关闭形式:

public MainWindow() 
{ 
    InitializeComponent(); 

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

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

我们可以采取史蒂夫的一个答案进一步创建一个附加属性,为任何窗口提供“关闭换码”功能。写一次财产并在任何窗口中使用它。只需添加下面的窗口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(); 
    } 
} 
+3

是的。附加属性在我的脑海中仍然不会“点击”。 – Gishu 2009-02-05 08:35:33

+0

工程很好,唯一的是我必须替换铸造到窗口,并添加一个检查null为空,如此处所示 - http://stackoverflow.com/questions/10206742/unable-to-cast-object-of-type -microsoft-expression-platform-wpf-instancebuilder,以避免错误“无法将类型为”Microsoft.Expression.Platform.WPF.InstanceBuilders.WindowInstance“的对象转换为键入”System.Windows.Window“”(项目能够构建成功,但错误很烦人,这是为了我的VS 2012 + R#,并且在此之后,我必须重新启动VS. – sarh 2015-02-12 22:21:39

6

这是不完全正确是... MSDN这样说:当您设置将按钮的IsCancel属性设置为true,您将创建一个在AccessKeyManager中注册的Button。当用户按ESC键时,该按钮被激活。 所以你需要在后面 代码中的处理程序,并就不需要任何附加属性或类似的东西在WPF的AcceptButton是

1

是的,这是right.In Windows应用程序和取消按钮是存在的。但有一点是,如果您将控件可见性设置为false,那么它将无法按预期工作。为此,您需要在WPF中将可见性设置为true。例如:(它不工作了取消按钮,因为这里的能见度为false)

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