Question

L’idée de base du bouton Annuler est d’autoriser la fermeture de la fenêtre avec une touche d'échappement.

  

Vous pouvez définir la propriété IsCancel sur   le bouton Annuler à true, entraînant la   Bouton Annuler pour fermer automatiquement   le dialogue sans gérer le clic   événement.

Source: Programmation WPF (Griffith, Sells)

Cela devrait donc fonctionner

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

Cependant, le comportement que je prévois ne fonctionne pas pour moi. La fenêtre parente est la fenêtre principale de l'application spécifiée par la propriété Application.StartupUri. Ce qui fonctionne est

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

private void CloseWindow(object sender, RoutedEventArgs) 
{
    this.Close();
}
  • Le comportement de IsCancel est-il différent selon que la fenêtre est une fenêtre normale ou un dialogue? Est-ce que IsCancel fonctionne comme annoncé uniquement si ShowDialog a été appelé?
  • Un gestionnaire de clic explicite est-il requis pour que le bouton (avec IsCancel défini sur true) ferme une fenêtre sur une pression d'échappement?
Était-ce utile?

La solution

Oui, cela ne fonctionne que sur les boîtes de dialogue, car une fenêtre normale n'a pas de notion "d'annulation", c'est la même chose que DialogResult.Cancel retournant de ShowDialog dans WinForms.

Si vous souhaitez fermer une fenêtre avec échappement, vous pouvez ajouter un gestionnaire à PreviewKeyDown dans la fenêtre, indiquez s'il s'agit de Key.Escape et fermez le formulaire:

public MainWindow()
{
    InitializeComponent();

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

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

Autres conseils

Nous pouvons pousser la réponse de Steve un peu plus loin et créer une propriété attachée fournissant le "d'échappement à la fermeture". fonctionnalité pour n'importe quelle fenêtre. Ecrivez la propriété une fois et utilisez-la dans n’importe quelle fenêtre. Ajoutez simplement ce qui suit à la fenêtre XAML:

yournamespace:WindowService.EscapeClosesWindow="True"

Voici le code de la propriété:

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

Ce n’est pas tout à fait ça, c’est ... MSDN dit ceci: Lorsque vous définissez la propriété IsCancel d'un bouton sur true, vous créez un bouton enregistré avec AccessKeyManager. Le bouton est alors activé lorsqu'un utilisateur appuie sur la touche ESC. Donc, vous avez besoin d'un gestionnaire dans votre code derrière Et vous n'avez besoin d'aucune propriété attachée ou quoi que ce soit de ce genre

Oui, c’est bien.Avec Windows, l’application WPF AcceptButton et le bouton Annuler sont là. Mais une chose est que si vous définissez votre visibilité de contrôle sur false, elle ne fonctionnera pas comme prévu. Pour cela, vous devez définir une visibilité aussi vraie que dans WPF. Par exemple: (cela ne fonctionne pas pour le bouton Annuler car ici la visibilité est fausse)

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

Donc, vous devez le faire:

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

Ensuite, vous avez écrit btnClose_Click dans le code derrière le fichier:

private void btnClose_Click (object sender, RoutedEventArgs e)
    { this.Close(); }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top