4

私は最近、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の不正行為のようです。:)ClickTabItem

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}">

注:バインドパスは、もちろん、ビューとビューモデルの設定方法によって異なる場合があります。

4

2 に答える 2

3

最善かつ正しい方法は、コマンドを作成することです。異なるフレームワークICommandでは、通常、パラメーターを使用する場合とパラメーターを使用しない場合の 2 つの実装があります (多くの場合、それは必要ありません)。

MVVM light にも 2 つのICommand実装がありますRelayCommandRelayCommand<T>

于 2012-06-19T09:10:01.923 に答える
2

独自の実装を作成することをお勧めします。DelegateCommandこれを行う方法の良い例は、こちらまたはこちらにあります。または Prismバリアントを使用してください。ここからダウンロードできます。

DelegateCommand を使用すると、ViewModel に引数を渡すことができます。

于 2012-06-19T09:11:55.820 に答える