MVVM

2016-08-26 7 views
1

のクラス初期化した後、私は自分のアプリケーションが初期化され、メインウィンドウが表示された後、次の行のコードを実行したい:MVVM

if (System.IO.File.Exists("token")) 
{ 

    string[] startupStrings = Environment.GetCommandLineArgs(); 
    await _myOneDrive.SilentLogIn(); 
    IsActive = true; 
    if (startupStrings.Length > 1 && startupStrings[1] == "/a") 
    { 
     IsWorking = true; 
     IsActive = false; 
     await _myOneDrive.EjectSynchroProcedure(false); 
     IsActive = true; 
     IsWorking = false; 
     Application.Current.Shutdown(); 
    } 
} 

私が使用できないため、残念ながら、私はこれを行うことができませんMVVMモデルコンストラクタのawaitオペレータLoadedにサインアップすると、MVVMのアイデアが壊れてしまいます。 async voidを一般的に使用するのではなく、Event Handlerの論理的な同等物でのみ使用しています。だから私の非同期コマンドは次のようになります。

async void SilentLogin(object parameter) 
{ 
    await _myOneDrive.SilentLogin(); 
    IsActive = true; 
} 

その後、私は私のコンストラクタでそれらを初期化し、XAMLコード内のボタンにコマンドをバインドします。

public MainWindowViewModel() 
{ 
    _myOneDrive = new MyOneDriveClient(PathPcDirectory, PathOneDriveDirectory, this); 
    LoginCommand = new RelayCommand(Login); 
    SilentLoginCommand = new RelayCommand(SilentLogin); 
    Console = "Program started"; 
} 

それだけで正常に動作しますが、私はまだ初期化後のコードを実行しているの私の目標を達成することはできません。私はvoidではないのでasync void Login(object parameter)コマンドを待つことができません。Taskです。さらに、RelayCommandでは有効ではないため、Taskに変更することはできません。だから、私はこのループの中で、実際にヒントやヒントを使ったり、間違いを指摘したりします。

+2

ViewのLoadedイベントからViewModelの 'Initialize'メソッドを呼び出しても問題はありません。 MVVMに違反しているとは思わない。 – Euphoric

+0

私は@ユーフォリックに同意します。ビュー_is_はVMについて知っています。それへのバインディングの表示と使用。 MVVMの目的は、VM _not_がそのプロパティがViewでどのように表現されるか心配することですが、ViewがVMの操作方法を知らないことを意味するものではありません。 – Sam

+0

ありがとうございます。それは明らかにうまく動作します。私はコードビハインドを使わないように私の心を奪われましたが、より良い解決策であるようです。私は 'Dispatcher'を使って試しましたが、早く始まりました。 – tweant

答えて

0

私は同様の問題があり、非常に単純なAsyncRelayCommandの実装が見つかりました。

public class AsyncRelayCommand : RelayCommand 
{ 
    private readonly Func<Task> _asyncExecute; 

    public AsyncRelayCommand(Func<Task> asyncExecute) 
     : base(() => asyncExecute()) 
    { 
     _asyncExecute = asyncExecute; 
    } 

    public AsyncRelayCommand(Func<Task> asyncExecute, Action execute) 
     : base(execute) 
    { 
     _asyncExecute = asyncExecute; 
    } 

    public Task ExecuteAsync() 
    { 
     return _asyncExecute(); 
    } 

    public override void Execute(object parameter) 
    { 
     _asyncExecute(); 
    } 
} 

それからちょうどタスクを返却し、新しく作成したAsyncRelayCommandによってRelayCommandの使用を置き換えるためにあなたの方法を変更します。私のためにうまくいった。

パラメータを使用することはおそらくまだ機能しない可能性があるので、これについてはさらに実装する必要があります。私の場合、それは必要ではありませんでした。しかし、あなたは基本的な考えを得るべきです。

+0

あなたはそうです。それは正常に働いた。それにもかかわらず、単純な 'RelayCommand'と' async void'を使って動作しました。私の問題は、そのコマンドを取り出す方法か、開始時に関数を待つことでした。私は 'Loaded'イベントを使うことにしました。 – tweant