Как работает кнопка WPF.Свойство IsCancel?
Вопрос
Основная идея кнопки Отмены заключается в том, чтобы включить закрытие вашего окна нажатием клавиши Escape.
Вы можете установить свойство IsCancel для кнопки Отмена в значение true, в результате чего Кнопка Отмена автоматически закроется диалоговое окно без обработки события Click .
Источник:Программирование WPF (Гриффит, Продает)
Так что это должно сработать
<Window>
<Button Name="btnCancel" IsCancel="True">_Close</Button>
</Window>
Однако поведение, которого я ожидаю, мне не подходит.Родительское окно - это главное окно приложения, указанное приложением.Свойство StartupUri.Что работает, так это
<Button Name="btnCancel" IsCancel=True" Click="CloseWindow">_Close</Button>
private void CloseWindow(object sender, RoutedEventArgs)
{
this.Close();
}
- Отличается ли поведение IsCancel в зависимости от того, является ли окно обычным окном или диалоговым?Работает ли IsCancel так, как объявлено, только в том случае, если был вызван ShowDialog?
- Требуется ли явный обработчик щелчка для кнопки (с IsCancel, установленным в true), чтобы закрыть окно при нажатии Escape?
Решение
Да, это работает только в диалоговых окнах, поскольку в обычном окне нет понятия "отмена", это то же самое, что DialogResult .Отменить возврат из ShowDialog в WinForms.
Если вы хотите закрыть окно с помощью escape, вы могли бы добавить обработчик к PreviewKeyDown в окне, определить, является ли это Key.Escape и закрыть форму:
public MainWindow()
{
InitializeComponent();
this.PreviewKeyDown += new KeyEventHandler(CloseOnEscape);
}
private void CloseOnEscape(object sender, KeyEventArgs e)
{
if (e.Key == Key.Escape)
Close();
}
Другие советы
Мы можем сделать ответ Стива еще на один шаг дальше и создать прикрепленное свойство, которое обеспечивает функциональность "escape on close" для любого окна.Запишите свойство один раз и используйте его в любом окне.Просто добавьте следующее в window 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.Затем кнопка активируется, когда пользователь нажимает клавишу ESC.Итак, вам действительно нужен обработчик в вашем коде позади И вам не нужны никакие прикрепленные свойства или что-то в этом роде
Да, это верно.В приложении Windows в WPF есть AcceptButton и кнопка отмены.Но одна вещь заключается в том, что если вы устанавливаете видимость вашего элемента управления как false, то это не будет работать должным образом.Для этого вам нужно сделать видимость равной true в WPF.Например:(это не работает для кнопки Отмены, потому что здесь видимость ложная)
<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(); }