Pergunta

A idéia básica por trás de um botão Cancelar é permitir fechar a janela com uma Fuga Keypress.

Você pode definir a propriedade IsCancel em o botão Cancel para true, fazendo com que o botão Cancelar para fechar automaticamente de diálogo sem manusear o Click evento.

Fonte: Programação WPF (Griffith, vende)

Então, isso deve funcionar

<Window>
<Button Name="btnCancel" IsCancel="True">_Close</Button>
</Window>

No entanto, o comportamento Espero não está funcionando para mim. A janela principal é a janela principal do aplicativo especificado pela propriedade Application.StartupUri. O que funciona é

<Button Name="btnCancel" IsCancel=True" Click="CloseWindow">_Close</Button>

private void CloseWindow(object sender, RoutedEventArgs) 
{
    this.Close();
}
  • É o comportamento de IsCancel diferente com base em se a janela é uma janela normal ou uma caixa de diálogo? Does IsCancel trabalho como anunciado somente se ShowDialog foi chamado?
  • É um manipulador Click explícita necessária para o botão (com IsCancel conjunto para true) para fechar uma janela em um pressione Escape?
Foi útil?

Solução

Sim, ele só funciona em caixas de diálogo como uma janela normal tem nenhum conceito de "cancelamento", é o mesmo que DialogResult.Cancel retornando de ShowDialog em WinForms.

Se você quiser fechar uma janela com a fuga você poderia adicionar um manipulador para PreviewKeyDown na janela, captador sobre se é Key.Escape e fechar o formulário:

public MainWindow()
{
    InitializeComponent();

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

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

Outras dicas

Podemos tomar de Steve resposta um passo adiante e criar uma propriedade anexada que fornece a "fuga numa estreita" funcionalidade para qualquer janela. Escrever a propriedade uma vez e usá-lo em qualquer janela. Basta adicionar o seguinte para o XAML janela:

yournamespace:WindowService.EscapeClosesWindow="True"

Aqui está o código para a propriedade:

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

Isto não está certo é que ... MSDN diz o seguinte: Quando você definir a propriedade IsCancel de um botão para true, você cria um botão que está registrado com o AccessKeyManager. O botão é então ativado quando o usuário pressiona a tecla ESC. Então você precisa de um manipulador em sua por trás de código E você não precisa de quaisquer propriedades anexadas ou qualquer coisa assim

Sim, este é right.In janelas de aplicações em WPF AcceptButton e Button Cancel está lá. Mas uma coisa é que se você está definindo a sua visibilidade controle como falsa, então não vai funcionar como expected.For que você precisa fazer como a visibilidade tão verdadeiro no WPF. Por exemplo: (ele não está funcionando para botão Cancelar porque aqui a visibilidade é falso)

<Button x:Name="btnClose" Content="Close" IsCancel="True" Click="btnClose_Click" Visibility="Hidden"></Button> 

Então, você precisa fazê-lo:

<Button x:Name="btnClose" Content="Close" IsCancel="True" Click="btnClose_Click"></Button>

Então você tem btnClose_Click escrita em código por trás do arquivo:

private void btnClose_Click (object sender, RoutedEventArgs e)
    { this.Close(); }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top