2016-02-03 7 views
0

Je suis nouveau dans WPF et surtout dans les Commandes, et j'ai actuellement pour tâche de construire une RelayCommand pour un bouton. Je suis supposé apprendre que j'ai besoin de séparer la logique de l'interface utilisateur. J'ai juste 2 textbox et un textBlock, l'utilisateur écrit les noms dans les cases et clique sur un bouton pour les afficher dans le bloc de texte. Ma tâche est de lire à propos de RelayCommand et de l'implémenter, mais je ne comprends vraiment pas comment cela fonctionne. J'ai une méthode UpdateName dans ma classe Logic.cs, comment l'utiliser dans un RelayCommand? Tout ce que j'ai est le RelayCommand.cs avec l'interface ICommand implémentée. C'est le code que j'ai trouvé en ligne, mais je ne sais vraiment pas quoi mettre où.RelayCommand pour la mise à jour d'un TextBox

public event EventHandler CanExecuteChanged 
{ 
    add { CommandManager.RequerySuggested += value; } 
    remove { CommandManager.RequerySuggested -= value; } 
} 
private Action methodToExecute; 
private Func<bool> canExecuteEvaluator; 
public RelayCommand(Action methodToExecute, Func<bool> canExecuteEvaluator) 
{ 
    this.methodToExecute = methodToExecute; 
    this.canExecuteEvaluator = canExecuteEvaluator; 
} 
public RelayCommand(Action methodToExecute) 
    : this(methodToExecute, null) 
{ 
} 
public bool CanExecute(object parameter) 
{ 
    if (this.canExecuteEvaluator == null) 
    { 
     return true; 
    } 
    else 
    { 
     bool result = this.canExecuteEvaluator.Invoke(); 
     return result; 
    } 
} 
public void Execute(object parameter) 
{ 
    this.methodToExecute.Invoke(); 
} 

Répondre

2

Vous ne mettez aucune logique dans le RelayCommand lui-même.

Je suppose que la vue où le Button est, a son DataContext ensemble à la classe Logic.cs, donc je suppose Logic.cs contient le viewmodel. Ainsi, dans le viewmodel vous ajoutez une nouvelle propriété:

public ICommand UpdateTextCommand { get; private set; } 

Dans le constructeur de viewmodel vous initialisez cette commande:

UpdateTextCommand = new RelayCommand(() => this.UpdateName(), null); 

Et dans la vue (XAML) vous liez la propriété de CommandButton:

<Button Content="Click me to change the TextBlock" Command="{Binding UpdateTextCommand}" /> 

Bien sûr, je ne suis pas familier avec la structure de votre application, cette liaison peut échouer. Mais c'est l'idée générale de commander.

Mise à jour: Le constructeur est la méthode sans type de retour (même pas void). Chaque fois que vous instanciez (new) une méthode class s'exécute.

Pour Logic il devrait être (si le nom class est Logic):

public Logic() 
{ 
    // Statements here 
} 

Pour RelayCommand c'est le constructeur:

public RelayCommand(Action methodToExecute, Func<bool> canExecuteEvaluator) 
+0

Oui, DataContext est défini sur la classe Logic. J'ai ajouté la propriété, mais où exactement initialiser la commande? Où est la construction de viewmodel, dans le Logic.cs? Désolé, je suis vraiment nouveau à ce sujet. La partie contraignante je comprends. – tweedledum11

+0

Mise à jour de la réponse. –

+0

Ok, je l'ai, j'ai initialisé la commande dans le constructeur Logic, par UpdateText() vous voulez dire ma méthode personnalisée UpdateName? Mon Visual Studio m'a fait changer à ceci: UpdateTextCommand = new RelayCommand (délégué (object obj) {UpdateName();}, null); Pourquoi donc? Celui d'avant n'a pas fonctionné. – tweedledum11

1

Vous devez implémenter votre méthode que vous voulez appeler votre ViewModel comme vous l'avez fait avec le CodeBehind-File avant de commencer avec MVVM.

Ensuite, vous devez créer un ICommand comme propriété dans votre viewmodel (pour la liaison par la suite):

private RelayCommand relUpdateText; 
public ICommand CUpdateTextCommand { get { return relUpdateText; } } 

Dans votre constructeur (de votre viewmodel), vous devez créer l'objet RelayCommand:

relUpdateText = new RelayCommand(OnUpdateText); 

Avec OnUpdateText étant la méthode que vous souhaitez appeler.

Ensuite, vous devez créer un constructeur avec les bons paramètres. Si votre OnUpdateText ressemble à ceci:

private void OnUpdateText(string text){...} 

Votre constructeur RelayCommand devrait ressembler à ça:

private Action<String> exec; 
public RelayCommand(Action<String> exec) 
{ 
    this.exec = exec; 
} 

Comme vous le voyez l'action ont besoin les mêmes paramètres que la méthode encapsule. A la fin, vous devriez également vérifier si l'événement est non nul:

public void Execute(object parameter) 
{ 
    if(exec != null) exec(paramters as string); 
} 

Si vous avez plus de paramètres, vous devrez utiliser un convertisseur.

+0

Merci beaucoup, cela le rend plus facile à comprendre! – tweedledum11