web-dev-qa-db-fra.com

Commande d'appel de code derrière

J'ai donc fait des recherches et je ne peux pas savoir exactement comment faire cela. Je crée un contrôle utilisateur à l'aide de MVVM et souhaite exécuter une commande sur l'événement 'Loaded'. Je me rends compte que cela nécessite un peu de code, mais je n'arrive pas à comprendre ce qui est nécessaire. La commande est située dans le ViewModel, qui est défini comme le contexte de données de la vue, mais je ne sais pas exactement comment l'acheminer pour pouvoir l'appeler à partir du code situé en arrière de l'événement chargé. Fondamentalement, ce que je veux, c'est quelque chose comme ça ...

private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
    //Call command from viewmodel
}

En regardant autour de moi, je n'arrive pas à trouver la syntaxe pour cela nulle part. Dois-je d'abord lier la commande dans le xaml pour pouvoir la référencer? Je remarque que l'option de liaison de commande dans un contrôle utilisateur ne vous laissera pas lier des commandes comme vous le pouvez dans quelque chose comme un bouton ...

<UserControl.CommandBindings>
    <CommandBinding Command="{Binding MyCommand}" /> <!-- Throws compile error -->
</UserControl.CommandBindings>

Je suis sûr qu'il existe un moyen simple de le faire, mais je ne peux pas le comprendre pour le moment. 

56
Kevin DiTraglia

Eh bien, si le DataContext est déjà défini, vous pouvez le lancer et appeler la commande:

var viewModel = (MyViewModel)DataContext;
if (viewModel.MyCommand.CanExecute(null))
    viewModel.MyCommand.Execute(null);

(Modifiez le paramètre si nécessaire)

118
H.B.

Préface: Sans en savoir plus sur vos exigences, il semble qu'une odeur de code exécute une commande à partir de code-behind lors du chargement. Il doit y avoir une meilleure façon, MVVM.

Mais, si vous avez vraiment besoin de le faire dans le code derrière, quelque chose comme ceci fonctionnerait probablement (note: je ne peux pas le tester pour le moment):

private void UserControl_Loaded(object sender, RoutedEventArgs e)     
{
    // Get the viewmodel from the DataContext
    MyViewModel vm = this.DataContext as MyViewModel;

    //Call command from viewmodel     
    if ((vm != null) && (vm.MyCommand.CanExecute(null)))
        vm.MyCommand.Execute(null);
} 

Encore une fois - essayez de trouver un meilleur moyen ...

5
Wonko the Sane

J'ai une solution plus compacte que je veux partager. Parce que j'exécute souvent des commandes dans mes ViewModels, j'en ai eu assez d'écrire la même déclaration if J'ai donc écrit une extension pour l'interface ICommand.

using System.Windows.Input;

namespace SharedViewModels.Helpers
{
    public static class ICommandHelper
    {
        public static bool CheckBeginExecute(this ICommand command)
        {
            return CheckBeginExecuteCommand(command);
        }

        public static bool CheckBeginExecuteCommand(ICommand command)
        {
            var canExecute = false;
            lock (command)
            {
                canExecute = command.CanExecute(null);
                if (canExecute)
                {
                    command.Execute(null);
                }
            }

            return canExecute;
        }
    }
}

Et voici comment vous exécuteriez une commande dans le code:

((MyViewModel)DataContext).MyCommand.CheckBeginExecute();

J'espère que cela accélérera un peu plus votre développement. :)

P.S. N'oubliez pas d'inclure également l'espace de noms ICommandHelper. (Dans mon cas, il s'agit de SharedViewModels.Helpers)

1
Stefan Vasiljevic

Essaye ça:

private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
    //Optional - first test if the DataContext is not a MyViewModel
    if( !this.DataContext is MyViewModel) return;
    //Optional - check the CanExecute
    if( !((MyViewModel) this.DataContext).MyCommand.CanExecute(null) ) return;
    //Execute the command
    ((MyViewModel) this.DataContext).MyCommand.Execute(null)
}
1
Alain

Vous avez peut-être également incorporé votre code dans n’importe quel MessaginCenter.Souscrire et travailler avec le modèle MessagingCenter . Si vous souhaitez uniquement exécuter quelque chose à partir du code situé au lieu de cliquer sur un bouton de vue avec la propriété Command, cela m’a parfaitement fonctionné.

J'espère que ça aide quelqu'un.

0
Joilson Cardoso