WPF Button.IsCancelプロパティはどのように機能しますか?
質問
キャンセルボタンの背後にある基本的な考え方は、Escキーを押してウィンドウを閉じることを有効にすることです。
IsCancelプロパティを設定できます [キャンセル]ボタンをtrueにすると、 自動的に閉じるキャンセルボタン クリックを処理しないダイアログ イベント。
出典: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が呼び出された場合にのみアドバタイズされますか?
- Escキーを押してウィンドウを閉じるには、ボタン(IsCancelをtrueに設定)に明示的なクリックハンドラーが必要ですか?
解決
はい、通常のウィンドウには「キャンセル」の概念がないため、ダイアログでのみ機能します。これは、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();
}
他のヒント
スティーブの回答をさらに一歩進めて、「閉じるときにエスケープ」を提供する添付プロパティを作成できます。任意のウィンドウの機能。プロパティを一度書いて、任意のウィンドウで使用します。ウィンドウ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();
}
}
これは正しくありません... MSDNは次のように述べています。ボタンのIsCancelプロパティをtrueに設定すると、AccessKeyManagerに登録されるButtonを作成します。ユーザーがESCキーを押すと、ボタンがアクティブになります。 そのため、コードビハインドにハンドラーが必要です。 また、添付プロパティなどは必要ありません
はい、これは正しいです。Windowsアプリケーションには、WPF AcceptButtonとCancel Buttonのアプリケーションがあります。ただし、1つは、コントロールの可視性を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(); }