84

だから私は周りを探していて、これを行う方法を正確に見つけることができません。MVVMを使用してユーザーコントロールを作成していて、「Loaded」イベントでコマンドを実行したいと思います。これには少しコードが必要だと思いますが、何が必要かを完全に理解することはできません。コマンドは、ビューのデータコンテキストとして設定されているViewModelにありますが、ロードされたイベントの背後にあるコードから呼び出すことができるように、これをルーティングする方法が正確にわかりません。基本的に私が欲しいのはこのようなものです...

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

周りを見回すと、この構文はどこにも見つからないようです。コマンドを参照できるようにするには、最初にxamlでコマンドをバインドする必要がありますか?ユーザーコントロール内のコマンドバインディングオプションでは、ボタンのようなもの内でできるようにコマンドをバインドできないことに気付きました...

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

これを行う簡単な方法があると確信していますが、私は一生それを理解することはできません。

4

6 に答える 6

161

DataContext が既に設定されている場合は、それをキャストしてコマンドを呼び出すことができます。

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

(必要に応じてパラメータを変更)

于 2012-04-12T15:44:01.137 に答える
8

序文: 要件について詳しく知らないと、ロード時にコード ビハインドからコマンドを実行するのはコードの匂いのように思えます。MVVMに関しては、より良い方法が必要です。

しかし、本当にコード ビハインドでそれを行う必要がある場合は、おそらく次のようなものが機能します (注: 現時点ではこれをテストできません)。

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

もう一度 - より良い方法を見つけてみてください...

于 2012-04-12T15:45:46.927 に答える
2

共有したい、よりコンパクトなソリューションがあります。ViewModel でコマンドを実行することが多いので、同じ if 文を書くのにうんざりしました。そこで、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;
        }
    }
}

これは、コードでコマンドを実行する方法です。

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

これにより、開発がもう少しスピードアップすることを願っています。:)

PS ICommandHelper の名前空間も含めることを忘れないでください。(私の場合は SharedViewModels.Helpers です)

于 2016-02-17T20:30:26.080 に答える
1

これを試して:

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)
}
于 2012-04-12T15:43:42.977 に答える