1

私はインターフェイス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()は機能しません。

4

1 に答える 1

0

まず、あなたが言う

私は DevExpress を使用しているため、DataContext を Main.xaml.cs ファイルに直接バインドできません。理由はまだわかりません。

Express はここでは問題になりません。適切な ViewModel を返すようにバインドする必要があります。このテーマに関する議論については、こちらをご覧ください。

第二に、あなたはエラーが

viewModelWrapper.ScreenModel でプロパティ DifferentProperty が見つかりません

これは必ずしも問題ではなく、例外は発生しません。バインディングを動的に変更すると、INotifyPropertyChanged イベントがあちこちに飛んでいき、「不確実」な期間が生じる場合があります。ViewModels が INotifyPropertyChanged を実装していると仮定しています。

例外がある場合、キーはおそらく例外を詳しく調べていると思います(「プロパティが見つかりません」はデバッグメッセージであり、例外ではないため)。明確にするために、ここで説明されているようにバインディング メッセージをオフにすることをお勧めします。実際の例外がある場合は、詳細を編集してください。

于 2012-06-26T02:10:53.367 に答える