2

私のダイアログには、TabControlChildViews usingがありPrismます。保存コマンドには、CompositeCommand. すべてが期待どおりに機能します。唯一の問題は、すべての ChildViewModel が非同期保存プロセスを完了するのを待ち、すべてが完了したらダイアログを閉じたいということです。

残念ながら、CompositeCommands はその機能をサポートしていません。では、ダイアログを閉じる前に、すべての ViewModel の作業が完了するまで待つにはどうすればよいでしょうか?

ここに画像の説明を入力

4

2 に答える 2

3

大丈夫。タスクベースの非同期パターンを使用すると、要件は簡単です。

AsynchronousCommandフレームワークにまだないものが必要です。少しの努力で自分で作ることができます。

public interface IAsyncCommand : ICommand
{
     Task ExecuteAsync(object parameter);
}

次のようになるこのインターフェースの複合実装が必要です

public class AsyncCompositeCommand : IAsyncCommand
{
    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    private readonly IEnumerable<IAsyncCommand> commands;
    private readonly Action<object> executedCallback;
    public AsyncCompositeCommand(IEnumerable<IAsyncCommand> commands, Action<object> executedCallback)
    {
        this.commands = commands;
        this.executedCallback = executedCallback;
    }

    public bool CanExecute(object parameter)
    {
        return commands.Any(x => x.CanExecute(parameter));
    }     

    public async Task ExecuteAsync(object parameter)
    {
        var pendingTasks = commands.Select(c=> c.ExecuteAsync(parameter))
                                    .ToList();
        await Task.WhenAll(pendingTasks);

        executedCallback(parameter);//Notify
    }

    public async void Execute(object parameter)
    {
        await ExecuteAsync(parameter);
    }
}

上記のクラスExecuteAsyncでは、他の子コマンドを並行して開始します。シーケンシャルにしたい場合は、ExecuteAsyncメソッドを以下の実装に置き換えることができます。

public async Task ExecuteAsync(object parameter)
{
    foreach (var cmd in commands)
    {
        await cmd.ExecuteAsync(parameter);
    }

    executedCallback(parameter);//Notify
}

executedCallbackすべての子コマンドが完了したときに呼び出されるデリゲートです。ウィンドウを閉じるコードをそのデリゲートにラップすることができます。

ビューモデルは次のようになります。

public class ViewModel
{
    public ICommand SaveCommand { get; private set; }

    public ViewModel()
    {
        SaveCommand = new AsyncCompositeCommand(new IAsyncCommand[] 
        {
            command1,
            command2,
            ...
        },
        param => Console.WriteLine("Done"));
    }
}

ViewModel.SaveCommandUI でプロパティをバインドする方法はあなた次第です。

于 2015-10-29T12:37:55.283 に答える