私は mvvm light を使用していますが、イベント コマンド機能を頻繁に使用する必要はありません。少し異なる方法で、同じ機能を管理しました。
<telerik:RadTabControl Template="{StaticResource TabControlTemplate}"
ItemsSource="{Binding TabbedViewModels }" SelectedItem="{Binding ActiveTabbedViewModel, Mode=TwoWay}"
ItemTemplate="{StaticResource TabItemTemplate}" Style="{StaticResource RadTabControlStyleBorderless}" />
そのため、メイン ウィンドウのビューモデルには、コントロールの項目ソースとしてバインドするタブ付き項目ごとに 1 つのビューモデルのコレクションがあります。次に、選択した項目をメイン ビュー モデルのプロパティにバインドします。次に、そのプロパティのセッターで、SelectionChangedEvent で行う必要がある特定のことを行うことができます。私の場合、タブのビューモデルはユーザーが開始したものに基づいて動的にロードされ、それぞれがかなり異なる可能性があるため、インターフェイスを使用することもできますが、すべて共通の基本クラスから継承します。したがって、コレクションはそのbasクラスのObservableCollectionであり、selectedItemがバインドするActiveTabbedViewModelプロパティもそのタイプです。
あなたのシナリオに適しているかどうかはわかりませんが、このアプローチを使用することで、相互作用トリガーは必要ありません
編集: もう少し詳しく説明します - 残念ながら、私はあなたを指すブログを知らないので、私がこれにどのようにアプローチしたかについてもう少し説明します
したがって、TabControl とコンテンツ フレームを含む MainPage.xaml です。MainPageViewModel は、メインページのビュー モデルです。TabbedWindowViewModelBase (この目的のために作成したクラス) の ObservableCollection である TabbedViewModels というプロパティがあります。
/// <summary>
/// Gets or sets a collection of TabbedViewModels - each one will be represented by a tab on the top bar of the main window
/// </summary>
public ObservableItemCollection<CastleTabbedWindowViewModelBase> TabbedViewModels
{
get
{
return this.tabbedViewModels;
}
set
{
this.tabbedViewModels = value;
this.RaisePropertyChanged(() => this.TabbedViewModels);
}
}
/// <summary>
/// Gets or sets the Active Tab - is bound to the Tab bars SelectedItem - when changing to
/// another tab / view model it sets the page menu item to the correct one for that view model
/// </summary>
public CastleTabbedWindowViewModelBase ActiveTabbedViewModel
{
get
{
return this.activeTabbedViewModel;
}
set
{
this.activeTabbedViewModel = value;
this.RaisePropertyChanged(() => this.ActiveTabbedViewModel);
if (value != null)
{
// when the active tab has changed want to ensure we open the previously opened page that the new tab was on
value.DoSomething();
}
}
}
この時点では、シナリオがどれほど複雑かによって異なります。同じビューを持っていて、データを変更しているだけの場合、ビューは ActiveTabbedViewModel にバインドできます。これは、propertychanged イベントが発生するためです。これにより、バインドが自動的に更新され、新しいタブに関連するデータが表示されます。子ビューモデルで DoSomething を使用して、そのデータを最初にロードすることができます。リフレッシュする必要がない限り、これを行う必要があるのは 1 回だけです。
あなたが説明したことから、これを回避する1つの方法は、以下の TabbedWindowViewModel クラスを作成することです:`
public class TabbedWindowViewModel :ViewModelBase
{
private RelayCommand<NavigationEventArgs> navigationCommand;
/// <summary>
/// Gets or sets the position /order that this tab item is relative to the other tab items
/// </summary>
public int MenuOrder { get; set; }
/// <summary>
/// Gets or sets the Navigation Id
/// </summary>
public int NavigationId { get; set; }
/// <summary>
/// Gets or sets the Title that will be displayed for this tab item
/// </summary>
public string Title { get; set; }
/// <summary>
/// Gets or sets the navigation target that will be navigated to when the tab item is clicked
/// </summary>
public string NavigationTarget { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the tab item is enabled
/// </summary>
public bool IsEnabled { get; set; }
/// <summary>
/// Gets the command for regular navigation.
/// </summary>
public virtual ICommand NavigationCommand
{
get
{
return this.navigationCommand
??
(this.navigationCommand =
new RelayCommand<NavigationEventArgs>(
this.ExecuteNavigationCommand, x => this.IsEnabled));
}
}
public void DoSomething()
{
//do whatever you need to
//then navigate to the correct page
this.NavigationCommand.Execute(null);
}
private void ExecuteNavigationCommand(NavigationEventArgs e)
{
NavigationManager.NavigateToView(this.NavigationTarget);
}
}
NavigationManager は、ナビゲーションを支援する静的ヘルパー クラスであることに注意してください。次に、ナビゲートする可能性のある各ビューは、MainPage からデータコンテキストを継承するため、2 つの選択肢があります。TabbedWindoViewModel に DataViewModel プロパティを設定し、ActiveTabbedWindow.DataViewModel を介してすべてをそれにバインドします。または、メイン ビュー モデルの子ビュー モデルごとにプロパティを用意し、そのプロパティに直接バインドします。
public SummaryViewModel SummaryViewModel
{
get
{
return this.summaryViewModel
?? (this.summaryViewModel = (SummaryViewModel)ViewModelFactory.GetPageViewModel<SummaryViewModel>());
}
}
お役に立てれば...