it-swarm.com.de

Rufen Sie den Befehl von hinten auf

Also habe ich herumgesucht und kann nicht genau herausfinden, wie das geht. Ich erstelle ein Benutzersteuerelement mit MVVM und möchte einen Befehl für das Ereignis 'Loaded' ausführen. Mir ist klar, dass dies ein wenig Code hinter sich bringt, aber ich kann nicht ganz herausfinden, was nötig ist. Der Befehl befindet sich im ViewModel, das als Datenkontext der Ansicht festgelegt ist. Ich weiß jedoch nicht genau, wie er das routen soll, sodass ich es aus dem Code hinter dem geladenen Ereignis aufrufen kann. Grundsätzlich möchte ich so etwas ...

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

Wenn ich mich umsehe, kann ich nirgendwo die Syntax dafür finden. Muss ich den Befehl zuerst in xaml binden, um darauf verweisen zu können? Ich stelle fest, dass die Befehlsbindungsoption innerhalb eines Benutzersteuerelements keine Befehle binden kann, wie Sie dies in einer Schaltfläche tun können.

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

Ich bin sicher, dass es eine einfache Möglichkeit gibt, dies zu tun, aber ich kann es nicht für mein Leben herausfinden. 

56
Kevin DiTraglia

Wenn der DataContext bereits festgelegt ist, können Sie ihn umwandeln und den Befehl aufrufen:

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

(Parameter nach Bedarf ändern)

118
H.B.

Vorwort: Ohne mehr über Ihre Anforderungen zu wissen, scheint es wie ein Codegeruch, wenn Sie beim Laden einen Befehl vom Code-Behind ausführen. Es muss einen besseren Weg geben, wenn es um MVVM geht.

Aber wenn Sie es wirklich im Code hinter sich machen müssen, würde so etwas wahrscheinlich funktionieren (Anmerkung: Ich kann das im Moment nicht testen):

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

Wieder - versuchen Sie einen besseren Weg zu finden ...

5
Wonko the Sane

Ich habe eine kompaktere Lösung, die ich teilen möchte. Da ich häufig Befehle in meinen ViewModels ausführe, habe ich es satt, dieselbe if-Anweisung zu schreiben. Also habe ich eine Erweiterung für die ICommand-Schnittstelle geschrieben.

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

Und so würden Sie den Befehl im Code ausführen:

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

Ich hoffe, dass dies Ihre Entwicklung ein wenig mehr beschleunigen wird. :)

P.S. Vergessen Sie nicht, auch den Namespace von ICommandHelper anzugeben. (In meinem Fall handelt es sich um SharedViewModels.Helpers)

1

Versuche dies:

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

Möglicherweise haben Sie Ihren Code auch in ein beliebiges MessaginCenter.Subscribe-Programm eingebettet und arbeiten mit dem MessagingCenter-Modell. Wenn Sie nur etwas vom Code aus ausführen möchten, anstatt auf eine Ansichtsschaltfläche mit der Command-Eigenschaft zu klicken, hat es für mich perfekt funktioniert.

Ich hoffe es hilft jemandem.

0
Joilson Cardoso