私はインターフェイスIScreenViewModelを持っています、そして私ができる問題を単純化するために
RedScreenViewModel : IScreenViewModel
GreenScreenViewModel : IScreenViewModel
など。これは、後続のすべてのカラー画面と同様に、RedScreenViewModelインスタンスを作成するRedScreenView.xamlがあることを意味します。
IScreenViewModel has some properties that you must implement e.g.
interface IScreenViewModel
{
public Color ScreenColor{get;set;}
}
すべてのviewmodelsインスタンスを保持するViewmodelWrapperクラスがあります。ScreenViewModels、MenuViewModelsなど... DevExpressを使用しているため、まだわからないため、Main.xaml.csファイルでDataContextを直接バインドすることはできません。たとえば、メインでは。持てない
ScreenLabel.DataContext = viewModelWrapper.ScreenViewModel
私は主にやらなければならないでしょう:
DataContext = viewModelWrapper;
このようにして、親ウィンドウはすべての子要素を見ることができます。
RedScreenView.xamlでは、次のようなものを使用できます。
<Label Background="ScreenViewModel.ScreenColor"/>
そしてうまくいけば、データバインディングはViewModelWrapperでIScreenViewModel.ScreenViewModelオブジェクトを見つけ、動的バインディング/ポリモーフィズムを使用して正しいScreenColorオブジェクトを使用する必要があります。
画面がより多くのプロパティを持つことができる場合があるので、たとえば、継承されたScreenColorプロパティとともにGreenScreenViewModelで、それはおそらく独自のプロパティを持つことができますDifferentProperty
。
問題は次のとおりです。ユーザーが必要とする画面に応じて画面オブジェクトを返すファクトリがあります。正しい画面オブジェクトを返しますが、ビューにそれ自体を更新するように通知すると、新しいオブジェクトを調べますが、間違ったXAMLを使用します。それが理にかなっているなら。ViewModelWrapperメソッドでこのようなことをします。
MainGui.ScreenWrapper.LayoutRoot.Clear() ;
MainGui.ScreenWrapper.Items.Clear() ;
MainGui.ScreenWrapper.LayoutRoot.Add(screenFactory.GetSelectedScreen("RedScreen").GetLayoutRoot()
MainGui.UpdateLayout() ;
ScreenViewModel = screenFactory.GetSelectedScreen("RedScreen").GetViewModel() ;
ファクトリを2回呼び出したという事実を無視してください...ScreenWrapperは、画面を保持するLayoutGroupです。そのコードを使用してビュー(画面)を交換するとき、正しいバインディングが使用されることを期待しています。つまり、GreenScreenViewModelからRedScreenViewModelにスワップしたとしましょう。GreenScreenViewModelは、RedScreenViewModelよりも1つ多いプロパティであり、GreenScreenViewには次のようなものがあります。
<Label Content="ScreenViewModel.DifferentProperty"/>
スワップが完了し、ScreenViewModelがRedScreenViewModelを指していることを通知すると、例外がスローされます。これは、レイアウトが更新されておらず、まだ間違ったビューを使用しているためだと強く思います。デバッグモードでの出力エラーは、「viewModelWrapper.ScreenModelでプロパティDifferentPropertyが見つかりません」です。これは、GreenScreenViewをすでに削除しているため、正しくありません。レイアウトを更新しました。LayoutChangedイベントなどがあることがわかっているので、次のようになります。同様に発生しているのに、なぜまだ間違ったビューが表示されているのですか?ScreenWrapper.LayoutRootを更新して、別のバインディングコードで新しいビューを「表示」するにはどうすればよいですか。天国、それが明らかだったと思います。編集:マイケルで返信してくれてありがとう。はい、実際の例外があります-「NullReferenceException」私が使用しているサードパーティのdllで。そして、それはそれがプロパティを見つけることができないからです。はっきりしなかったと思いますが、おそらく質問は次のようになります。ビジュアルツリーからユーザーコントロールを削除および挿入する場合-ビジュアルツリーを更新して新しいバインディングを表示するにはどうすればよいですか?ビジュアルツリーを更新できれば、問題は解決するはずです。UpdateLayout()が機能しない
編集:マイケルで返信してくれてありがとう。はい、実際の例外があります-私が使用しているサードパーティのdllに「NullReferenceException」があります。そして、それはそれがプロパティを見つけることができないからです。OnPropertyChangedを呼び出すと例外がスローされますが、ハンドラーはnullではありません。はっきりしなかったと思いますが、おそらく質問は次のようになります。ビジュアルツリーからユーザーコントロールを削除および挿入する場合-ビジュアルツリーを更新して新しいバインディングを表示するにはどうすればよいですか?ビジュアルツリーを更新できれば、問題は解決するはずです。UpdateLayout()は機能しません。