28

ビューの背後にあるコード内にメソッドがあります(このメソッドはUIに何かを行います)。

とにかく、ViewModelからこのメソッドをトリガーしたいと思います。これはどのように行うことができますか?

4

6 に答える 6

33

MVVM に関する私 (そしておそらく他の人?) の問題は、単純なことを理解することでした: View は ViewModel について知っています。バインディングとコマンドを使用していましたが、.NET では単純stringsですxaml。実行時に安全に解決されるため (安全とは、タイプミスをしてもソフトウェアがクラッシュしないことを意味します)、これによりビューがビューモデルから切り離されます (少なくともコンパイル時には)。そして、私は常に、このデカップリングを維持するための解決策、たとえば行動を探していました。

DataContext真実は、通常はウィンドウ/ユーザー コントロールのビュー モデルに直接アクセスできることです。

var vm = (MyViewModel)this.DataContext;

ビューモデルはサブスクライバーが存在するかどうかを認識しないため、イベントを使用してビューモデルからビューメソッドを呼び出すのがおそらく最良の方法であることを知っていると、そのイベントとイベントを発生させるだけで、ビューまたは別のビューモデルで使用できます。

// define in the view model
public delegate void MyEventAction(string someParameter, ...);
public event MyEventAction MyEvent;

// rise event when you need to
MyEvent?.Invoke("123", ...);

// in the view
var vm = (MyViewModel)DataContext;
vm.MyEvent += (someParameter, ...) => ... // do something
于 2014-09-25T12:29:01.347 に答える
10

View(コードビハインド)でこのようにすることができます。

ViewModel によって実装されるインターフェイスにキャストするため、特定の ViewModel タイプに制約されることはありません。

    // CONSTRUCTOR
    public SomeView()
    {
        InitializeComponent();

        DataContextChanged += DataContextChangedHandler;
    }

    void DataContextChangedHandler(object sender, DependencyPropertyChangedEventArgs e)
    {
        var viewModel = e.NewValue as IInterfaceToBeImplementedByViewModel;

        if (viewModel != null)
        {
            viewModel.SomeEvent += (sender, args) => { someMethod(); }
        }
    }
于 2015-07-31T20:03:22.000 に答える
4

MVVMパターンによると、ViewModelはViewを認識しないため、これは受け入れられません。ViewModelを操作するには、Viewがコマンドをトリガーする可能性があります。また、バインディングを使用することもできます。さらに、BusyIndi​​catorなどのUI固有のものをViewModelレベルに移動しないでください。

ビューのメソッドを呼び出す場合と、このメソッドの機能など、具体的なユースケースに関する詳細を提供してください。

于 2011-12-28T16:29:04.080 に答える
0

上記の回答に対するあなたの返信を見ました。あなたは、ViewModelにデータを取得させてから、ビューにビジーインジケーターを停止するように指示していると言っています。

私の解決策が最善の解決策であるかどうかはわかりませんが、試してみることができます。私が間違っている場合は、誰かが修正できるかもしれません。

したがって、あなたの視点からは、ViewModelからメソッドを呼び出して、データセットの読み取りを開始します。このメソッドでは、デリゲート(ビューに存在するメソッドを指す)を渡すことができ、ViewModelがサーバーからのデータセットの読み取りを終了したら、ビュー内のメソッドにリンクされているデリゲート(ビューモデルから)をトリガーします。ビジーインジケーターを停止できます。

だからあなたの見解ではあなたは

void StopBusyIndicator()
{
    this.BusyIndicator.IsBusy = false;
}

ビューモデルを呼び出してデータセットを読み取ると、

このように呼んでください:

ViewModel.ReadDataSet( ()= >StopBusyIndicator)

これは、StopBusyIndi​​catorメソッドをデリゲートとして渡します。これは、ReadDataSetの最後で呼び出すことができます。

HTH

于 2011-12-28T16:41:21.810 に答える
0

Data Transfer オブジェクトを受け入れるアクション クラスを作成できます。DTO 内で、「View」というプロパティを追加し、現在のビューに割り当てます。ビューのコード ビハインド内からコントローラーを介してアクションを呼び出し、DTO をアンボックスすると、アクション クラス内でビューを完全に制御できるようになります。

モデルでこれを本当に実行したい場合は、モデルで「ビュー」タイプのパラメーターを使用してメソッドを作成し、それを実行して、現在のビューを渡します。

于 2011-12-28T16:46:19.593 に答える