私は最近、WPFでMVVMパターンを学習していて、最初の適切でかなり大きなアプリケーションを作成し始めました。これまでのところ、すべてスムーズな航海であり、私は私がたくさん見ているものが好きです。しかし、私は最近、つまずきの何かに遭遇しました。
アプリケーションはメインで構築されておりTabControl
、それぞれTabItem
にかなり大きな詳細ビューが含まれています。
TabControl inside main View, ItemsSource bound to MainViewModel.OpenTabs
TabItem with data specific View+ViewModel
TabItem with data specific View+ViewModel
TabItem with data specific View+ViewModel
etc...
OpenTabs
コレクションはonObservableCollection<BaseViewModel>
でMainViewModel
あり、TabControl
'sSelectedItem
はにバインドされていMainViewModel.ActiveTab
ます。
ここまでは順調ですね!しかし、私が得ているかどうかわからないのは、MVVMをフォローしながらタブのクローズを処理する方法です。(正しく学習するために)MVVMを厳密にしようとしていない場合は、MouseDown
-ヘッダーに-eventをバインドTabItem
して、そのイベントでクリックされたアイテムへの参照を取得し、それを削除します。OpenTabs
そのようにコレクション。しかし、私が間違っていない限り、効果的で適切なMVVMを実現するために、インタラクションロジックは実際のUIアイテムへの参照を必要としないはずです。
では、このMVVMスタイルをどのように処理しますか?特定のパラメーターを一緒に送信するコマンドを使用しますMainViewModel
か?MVVMでの推奨される実装はICommand
、オブジェクトパラメータを使用しないようです(MVVM Lightやその他のチュートリアルを見てください)。
CloseTab(int id)
自分でパブリックメソッドを作成し、閉じるボタンMainViewModel
をキャッチした後、背後のビューコードからそれを呼び出す必要がありますか?これはMVVMの不正行為のようです。:)Click
TabItem
TabItem
また、最後の注意点です。これは、現在アクティブではないaをクリックしても機能するはずです。それ以外の場合は、を使用してセットアップするのは難しくありませんOpenTabs.Remove(ActiveTab)
。
助けてくれてありがとう!また、これらの問題に関して推奨される読書/視聴へのリンクをいただければ幸いです。
解決策:コマンドパラメータを受け入れることができるコマンドを使用するのが最善の方法のようです。MVVMLightフレームワークのRelayCommandを使用しました。
MainViewModelの場合:
CloseTabCommand = new RelayCommand<BaseViewModel>((vm) =>
{
OpenTabs.Remove(vm);
});
XAMLの場合:
<Button
Command="{Binding Source={StaticResource MainViewModel}, Path=CloseTabCommand}"
CommandParameter="{Binding}">
注:バインドパスは、もちろん、ビューとビューモデルの設定方法によって異なる場合があります。