33

キャンセル ボタンの背後にある基本的な考え方は、エスケープ キーを押してウィンドウを閉じられるようにすることです。

[キャンセル] ボタンの IsCancel プロパティを true に設定すると、[キャンセル] ボタンは Click イベントを処理せずにダイアログを自動的に閉じることができます。

出典: 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 の動作は異なりますか? IsCancel は、ShowDialog が呼び出された場合にのみ宣伝どおりに機能しますか?
  • Escape キーを押してウィンドウを閉じるには、(IsCancel が true に設定された) ボタンに明示的な Click ハンドラーが必要ですか?
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 に登録されたボタンが作成されます。ユーザーが ESC キーを押すと、ボタンがアクティブになります。したがって、コードビハインドにハンドラーが必要であり、添付プロパティなどは必要ありません

于 2011-12-01T01:22:16.150 に答える
2

はい、これは正しいです。WPFのWindowsアプリケーションでは、AcceptButtonとCancel Buttonがあります。ただし、コントロールの可視性を 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(); }
于 2012-06-11T09:57:58.547 に答える