私は WPF MVVM (Light) を初めて使用するので、助けが必要です。
私が持っているのは、マスター/詳細シナリオ、メイン ビューの TabControl、最初のタブのマスター ビュー (ProductsView)、および次のタブの複数の異なる詳細ビュー (例: DetailsView) です。
ProductsView で選択された項目 (SelectedProduct) に応じて、DetailsView で項目を取得したいのですが、すぐには取得したくありません。ユーザーがこの詳細ビューを含むタブ項目をクリックしたときだけです。
そのため、データベースからの詳細データの取得は、ユーザーが適切な詳細タブをクリックするまで延期する必要があります (まったくクリックしない可能性があります)。
これが私のxamlです:
<!-- Main View -->
<UserControl x:Class="MyApp.Views.MainView">
<TabControl>
<TabControl.Items>
<TabItem>
<views:ProductsView />
</TabItem>
<TabItem>
<views:DetailsView />
</TabItem>
<!-- More TabItems with details views -->
</TabControl.Items>
</TabControl>
</UserControl>
<!-- Products View -->
<UserControl x:Class="MyApp.Views.ProductsView">
<Grid DataContext="{Binding Source={StaticResource Locator}, Path=ProductsVM}">
<DataGrid ItemsSource="{Binding Products}" SelectedItem="{Binding SelectedProduct}">
<DataGridTextColumn Binding="{Binding Path=Model.ProductID}" Header="Product ID" />
</DataGrid>
</Grid>
</UserControl>
<!-- Details View -->
<UserControl x:Class="MyApp.Views.DetailsView">
<Grid DataContext="{Binding Source={StaticResource Locator}, Path=DetailsVM.Details}">
<StackPanel>
<TextBox Text="{Binding Path=Model.Field1}" />
<TextBox Text="{Binding Path=Model.Field2}" />
</StackPanel>
</Grid>
</UserControl>
そしてコード:
public class ProductsViewModel : ViewModelBase
{
private ObservableCollection<Product> products;
public ObservableCollection<Product> Products
{
get
{
return products;
}
set
{ // RaisePropertyChanged
Set("Products", ref products, value);
}
}
private Product selectedProduct;
public Product SelectedProduct
{
get
{
return selectedProduct;
}
set
{ // RaisePropertyChanged and broadcast message of type PropertyChangedMessage<Product>
Set("SelectedProduct", ref selectedProduct, value, true);
}
}
public ProductsViewModel(IDataService dataService)
{
this.dataService = dataService;
Products = dataService.GetAllProducts();
}
}
public class DetailsViewModel : ViewModelBase
{
private Details details;
public Details Details
{
get
{
return details;
}
set
{ // RaisePropertyChanged
Set("Details", ref details, value);
}
}
public DetailsViewModel(IDataService dataService)
{
this.dataService = dataService;
Messenger.Default.Register<PropertyChangedMessage<Product>>(this, m => Details = dataService.GetDetails(m.NewValue.Model.ProductID));
}
}
これで機能しますが、製品を選択すると、すべての詳細がすべての詳細タブですぐに取得されます。ユーザーがMainViewのタブをクリックすると、MainViewModelはタブインデックスを含むメッセージをProductviewModelに送信し、ProductviewModelはSelectedProductを現在要求されているタブアイテムのDetailsViewModelに渡す別のメッセージをタブインデックスに基づいて送信する必要があります。詳細データを更新します。
しかし、すべてではなく、タブ インデックスに基づいて、現在要求されている tabitem/DetailsView にのみメッセージを送信するにはどうすればよいでしょうか。
また、このラウンドトリップは複雑すぎるように思えます。いくつか提案をいただけますか?それとも、これは完全に間違っていますか?たぶん、これに対する別の、よりシンプルでエレガントなソリューションがありますか?