3

私の MVVM アプリには、「ID」プロパティを公開する基本ユーザー コントロールから継承するビューが多数あります。XAML では、これはビューの基になるビュー モデルの ID プロパティにバインドされます。

Id="{Binding Path=Id}"

ビュー モデルは INotifyPropertyChanged を実装し、その ID はコンストラクターで設定されます。ID は、各ビュー/ビュー モデルを一意に識別するために使用され、主に、MDI アプリのように、メイン ウィンドウ内のユーザー コントロールを管理するために「デスクトップ マネージャー」によって使用されます。アプリが起動したら、さまざまなビュー モデルとそのビューをインスタンス化し、ビュー モデルをビューに割り当てますDataContext。次に、ビューをデスクトップ マネージャーに渡します。デスクトップ マネージャーは、ビューをキャンバスに配置したり、配置したりします。

私が抱えている問題は、ビューの ID がこの時点ではまだ null であり、しばらくしてからデータ コンテキストにバインドされているように見えることです (おそらく UI がレンダリングされたときですか?)。このようにバインディングを強制しようとしましたが、役に立ちません:-

var bindingExpression = widget.GetBindingExpression(DesktopElement.IdProperty);
bindingExpression.UpdateTarget();

ビュー モデルからビューとID をデスクトップ マネージャーに渡すことができるので、これで終わりというわけではありませんが、少しハッキーな感じがします。コントロール/ウィンドウのライフサイクルのどの時点でバインディングが発生するのか、バインディングを強制的に発生させる他の方法があるかどうかを知りたいと思っていましたか?

前もってありがとうアンディ

4

2 に答える 2

1

バインディングがどのように転送されるかを理解するには、Dispatcher. 基本的にはプライオリティキューです。レイアウト、バインディング、レンダリング、入力などは、さまざまな優先度でキューに配置されます。

さて、その音から、あなたは実行を に戻すことは決してありませんDispatcher。これは、Binding値を転送できないことを意味します (手動で呼び出すUpdateTargetと、 でこれをスケジュールしているだけですDispatcher)。つまり、Dispatcher初期化を完了する前に、キューに入れられた操作を実行させる必要があります。

BeginInvokeこれを行う最も簡単な方法は、メソッドの下位を呼び出してDispatcherPriority初期化を完了することです。レイアウト システムの仕組みの性質上、適切な優先順位を選択するのが難しい場合がありますが、DispatcherPriority.Loaded.

于 2013-06-27T20:38:06.287 に答える
0

私の提案は、View Models が実装する Id プロパティを公開するインターフェイスを持つことです。次に、適切なインターフェイスにキャストすることで、デスクトップ マネージャーに DataContext から Id を取得させることができます。Desktop Manager は (テスト容易性のために) 具体的な View について可能な限りほとんど知らないはずなので、これはおそらくより明確な責任の分離です。

于 2013-06-27T20:44:43.497 に答える