2010-11-25 12 views
1

Est-il possible d'avoir Alt +F4 (ainsi que le bouton de fermeture X + <system menu> :: Close) déclenchent le bouton qui est marqué comme IsCancel? Je voudrais qu'il se comporte de la même manière en appuyant sur la touche Esc.ALT + F4 et le bouton IsCancel

Note: J'utilise Prism et la boîte de dialogue est en cours de création dans un RegionBehavior je ne peux pas accéder directement sur le bouton

Répondre

0

J'ai fini par supporter cela via un comportement personnalisé, dont le code est ci-dessous. Je suis plus qu'heureux de passer à une implémentation plus propre (qui ne nécessite pas d'ajouter un comportement au bouton, par exemple) si quelqu'un peut y penser.

Quelques notes sur la mise en œuvre (qui est basé sur Rx):

  • Il suppose que cliquer sur le bouton d'annulation entraînera toujours dans la fenêtre fermée. Si votre bouton d'annulation peut être annulé (pour ainsi dire), le bouton ne sera pas cliqué lorsque la fenêtre est fermée.
  • Si le bouton est en quelque sorte retiré de la fenêtre (dans notre cas, un contenu différent est interverti dans une région), il va dissocier le comportement.
  • Tous les gestionnaires d'événements sont supprimés à la fin de la séquence, que la fenêtre ait été fermée, que le bouton ait été cliqué ou que le bouton ait été supprimé.

Et voici le code:

public class DialogCancelButtonBehavior : Behavior<Button> 
{ 
    protected override void OnAttached() 
    { 
     base.OnAttached(); 

     Button button = AssociatedObject; 

     GetWindowAsync(button) 
      .SelectMany(window => GetWindowClosed(window)) 
      .Where(_ => button.IsCancel) 
      .TakeUntil(GetButtonClicked(button)) 
      .TakeUntil(GetButtonUnloaded(button)) 
      .Subscribe(_ => ClickButton(button)); 
    } 

    private IObservable<Window> GetWindowAsync(Button button) 
    { 
     var buttonLoaded = Observable.FromEvent<RoutedEventHandler, RoutedEventArgs>(
      h => new RoutedEventHandler(h), 
      h => button.Loaded += h, 
      h => button.Loaded -= h); 

     return button.IsLoaded 
      ? Observable.Return(Window.GetWindow(button)) 
      : buttonLoaded.Take(1).Select(_ => Window.GetWindow(button)); 
    } 

    private IObservable<IEvent<EventArgs>> GetWindowClosed(Window window) 
    { 
     return Observable.FromEvent<EventHandler, EventArgs>(
      h => new EventHandler(h), 
      h => window.Closed += h, 
      h => window.Closed -= h); 
    } 

    private IObservable<IEvent<RoutedEventArgs>> GetButtonClicked(Button button) 
    { 
     return Observable.FromEvent<RoutedEventHandler, RoutedEventArgs>(
      h => new RoutedEventHandler(h), 
      h => button.Click += h, 
      h => button.Click -= h); 
    } 

    private IObservable<IEvent<RoutedEventArgs>> GetButtonUnloaded(Button button) 
    { 
     return Observable.FromEvent<RoutedEventHandler, RoutedEventArgs>(
      h => new RoutedEventHandler(h), 
      h => button.Unloaded += h, 
      h => button.Unloaded -= h); 
    } 

    private void ClickButton(Button button) 
    { 
     ButtonAutomationPeer peer = 
      (ButtonAutomationPeer)UIElementAutomationPeer.CreatePeerForElement(button); 

     IInvokeProvider invokeProv = 
      peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider; 

     invokeProv.Invoke(); 
    } 
} 
0

Alt + F4 doit déclencher le CloseCommand (RoutedUICommand, propriété de ApplicationCommands de classe statique). Si vous définissez un CommandBinding pour cette commande, vous devriez être capable de réagir dessus (c'est-à-dire d'appeler StopCommand ou d'annuler d'une autre manière) et de le marquer comme manipulé, sinon la fenêtre le gèrera et se fermera. Si cela n'est pas possible, vous pouvez simplement détacher le KeyGesture Alt + F4 de la commande CloseCommand (au démarrage de l'application) et le mapper à une autre action qui effectue votre annulation.

+0

Le problème est que mon code qui crée le 'Window' ignore complètement le bouton, et ne peut donc pas les relier. –