2017-08-15 4 views
0

J'apprends/pratique des solutions de base de cadre MVVM en C#Novice MVVM en C# en essayant de fermer l'application avec Esc (manipulation des commandes clés)

J'ai un petit programme qui joue avec un ComboBox, si l'utilisateur sélectionner quelque chose à partir de la boîte, il est affiché dans un MsgBox. Maintenant, je veux qu'il se ferme sur la touche Echap. J'ai trouvé beaucoup de questions à ce sujet ici résolus comme ceux-ci:

Keyboard events in a WPF MVVM application? Press Escape key to call method

Mais je suis incapable de mettre en œuvre l'un de ces ... Je ne semble même être en mesure de mettre KeyPreview True (Je suis d'accord pour écrire dans le formulaire maintenant, mais la chose amusante est, je ne peux pas le faire fonctionner.)

Mes problèmes sont, je n'ai pas utilisé C# pendant un certain temps, je ne sais pas quoi utiliser exactement (KeyEventArg KeyEventHandler, dois-je utiliser e.Key, e.keyDown?) Et je ne sais pas où mettre ce code. J'ai lu quelques trucs sur la façon de le faire dans le fichier XAML, ce qui serait le meilleur mais n'a pas pu le faire. En ce moment, voici mon code dans le App.xaml.cs, j'ai essayé de l'implémenter dans divers endroits, mais je demande quand Im codage et je ne sais pas quoi faire/quoi Mi faire exactement, donc ici Im.

Mon code en ce moment:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows; 
using System.Windows.Input; 

namespace WpfComboBoxStrinbgListMVVM 
{ 



    public class MainViewModel 
    { 

     public MainViewModel() 
     { 
      ItemList = new List<string> { "item1", "item2", "item3" }; 
     } 
     public List<string> ItemList { get; set; } 

     private string seletedElement; 
     public string SelectedElement 
     { 
      get { return seletedElement; } 
      set 
      { 
       seletedElement = value; 
       MessageBox.Show(seletedElement); 
      } 
     } 

     private void EscKeyDown(object sender, KeyEventArgs e) 
     { 

      if (e.Key == Key.Escape) 
      { 
       MessageBox.Show("Escape key pressed"); 
       // mainWindow.Close();? MainWievModel.Close(); App.Close(); 

      } 

     } 

     //private void Form1_KeyDown(object sender, KeyEventArgs e) 
     //{ 
     // if (e.KeyCode == Keys.Escape) 
     // { 
     //  MessageBox.Show("Escape key pressed"); 

     //  // prevent child controls from handling this event as well 
     //  e.SuppressKeyPress = true; 
     // } 
     //} 

    } 

} 
+0

Je suis incapable de faire apparaître la touche ESC enfoncée MsgBox, pls demander quoi que ce soit que vous avez besoin si vous voulez me aider :) –

+0

« maintenant, je veux fermer sur clé d'esc "- Qu'est-ce que" it "? –

+0

L'application elle-même, le programme, le tout (j'ai un autre projet où sur Esc la fenêtre de connexion disparaît mais fonctionne toujours dans le gestionnaire de tâches, je voudrais pouvoir le fermer correctement) –

Répondre

1

la méthode la plus simple dans ce cas serait d'utiliser la commande ApplicationCommands.Close prédéfinie

cela ressemblerait à ceci

<Window.InputBindings> 
    <KeyBinding Key="Esc" Command="ApplicationCommands.Close" /> 
</Window.InputBindings> 

puis dans le code

this.CommandBindings.Add(
    new CommandBinding(
    ApplicationCommands.Close, 
    (s,a)=>Application.Current.Shutdown() //or this.Close() depending on what you want to close 
) 
); 

autres options comprendraient la mise en œuvre d'une classe personnalisée qui utilise l'interface ICommand ou en utilisant l'une des centaines de bibliothèques qui offrent cette fonctionnalité telles que prism's Delegate Command ou Relay command

EDIT

que vous n'êtes pas familier avec les délégués anonymes le code derrière pourrait aussi être écrit comme ceci

this.CommandBindings.Add(
    new CommandBinding(
    ApplicationCommands.Close, 
    PerformClose 
) 
); 

public void PerformClose(object sender, ExecutedRoutedEventArgs args) 
{ 
    Application.Current.Shutdown(); 
} 
+0

Merci ... J'ai essayé beaucoup de différents approches comme ça, essayé Application.Fermer et App.Fermer et ceci.Fermer et etc ... Pouvez-vous m'expliquer ce que fait cette ligne? : (s, a) => Application.Current.Shutdown() et pourquoi en avons-nous besoin après ApplicationCommands.Close? et quels sont (s, a)? –

+1

'(s, a) =>' définit un délégué anonyme qui accepte 2 arguments dans ce cas objet s et eventAgs e, l'empreinte du gestionnaire d'événements standard, 'Application.Current' obtient l'application en cours d'exécution et la méthode shuddown est le commande pour fermer l'application sélectionnée – MikeT

+0

Je suis désolé si je vous dérange mais comment le programme sait-il que s est un type d'objet? a est eventArgs? et où sont-ils spécifiés? pour moi cela ressemble à quelque chose de magick noir que (s, a) => partie (et je veux comprendre non seulement l'implémenter) –

1

Vous pouvez utiliser KeyBinding, exemple de code comme ci-dessous:

<InputBindings> 
    <KeyBinding Key="Esc" Command="{Binding CloseCommand}"/> 
</InputBindings> 

En window.xaml (je crains que vous devez écrire un petit code derrière :()

Window(){ 
    InitializeComponent(); 
    this.DataContextChanged += (sender,e){ 
    var vm = e.NewValue as WindowViewModel; 
    if(vm != null){ 
     vm.CloseFunc =() => this.Close(); 
    } 
} 

}

Pour WindowViewModel: action publique CloseFunc {get; set;}

private RelayCommand _closeCommand; 
public RelayCommand CloseCommand => 
    _closeCommand??(_closeCommand = 
    new RelayCommand(() =>{ 
     CloseFunc?.Close(); 
    }))); 
+0

Salut, merci pour l'aide , mais je ne peux pas simplement utiliser la Binding CloseCommand comme n'importe quelle autre MVVM "commandes" comme ceci: [code] private string seletedElement; chaîne publique SelectedElement { get {return seletedElement; } défini { seletedElement = valeur; MessageBox.Show (seletedElement); } } [code] –

+0

@BasicHumanBeing Commande La liaison est la façon dont vous géreriez toutes les autres commandes, mais la méthode de gestion de cette liaison peut être effectuée de différentes manières. – MikeT

+0

@Jake, j'ai eu des erreurs dans le windiw.xaml et dans le WindowViewModel. Dans WVM: l'espace de noms action et relaycommands n'a pas pu être trouvé et dans window.xaml.cs (je suppose que c'est là où vous m'avez demandé de l'écrire) après expéditeur e) l'EDI excpect un "=>" et il ne reconnaît pas le CloseFunc (aussi Je n'ai jamais vu ça avant, qu'est-ce que ça fait: =() => n'est-ce pas simplement this.close devrait le faire?) –