1

WPF WebBrowser コントロールを実装するアプリケーションがあります。アプリケーションから、おそらく他のスレッドから呼び出す必要があるいくつかの JS 関数を含むページをロードします。できれば、MVVM パターンに固執し、関数の戻り値を解析するためのコードをモデルに保持したいと考えています。WebBrowser オブジェクトでの InvokeScript メソッドの呼び出しは、UI 要素であるため、Dispatcher スレッド (したがってビュー内) で発生する必要があります。

この仕事を成し遂げるために私が現在行っている手順は次のとおりです(大まかに擬似的に):

- subscribe to the LoadCompleted event of the browser (view)
- set the browser source (model -> viewmodel -> view)
- catch the LoadCompleted event (view -> viewmodel -> model)
- some logic (model)
- invoke script (model -> viewmodel -> view)
- get script result (view -> viewmodel -> model)
- some logic (model)

これにより、モデルとビューの間で (viewmodel を介して) かなりの通信が行われます。私は WPF (または MVVM については) の経験が少ないので、このタスクを達成するためのより適切な方法があるかどうか疑問に思っています (より適切な方法とは、モデル、ビューモデル、およびビュー間の呼び出しとイベントが少ないことを意味します)。

4

2 に答える 2

0

したがって、MVVM の主なポイントは、インターフェイス (プラットフォーム固有: windows\android\ios\windows phone など) を他のすべてのものから分離して、さまざまなプラットフォームでロジック (viewmodel\model) を再利用できるようにすることです。したがって、ビューモデルから InvokeScript を直接呼び出すことはできませんが、ディスパッチャーが原因ではないことは明らかです。ビューモデルで必要になる場合があるため、ディスパッチャーを抽象化できます(たとえば、 )。したがって、通常、viewmodel がビューで操作を実行する必要がある場合、イベント (または単にデリゲート) が使用されます。

public class MyViewModel
{
    public Func<string, object> InvokeScript { get; set; }
    public Func<string, Task<object>> InvokeScriptAsync { get; set; }

    public async void Something() {
        var result = await InvokeScriptAsync("my script");
        // do something
    }
}

そしてあなたの見解では:

public class MyView {
    private void OnViewModelChanged(MyViewModel vm) {
        vm.InvokeScript = text => Dispatcher.Invoke(() => browser.InvokeScript(text));
        vm.InvokeScriptAsync = text => browser.InvokeScriptAsync(text); // for example
    }
}
于 2016-04-01T22:19:17.410 に答える