Панели интерфейса с вкладками MVVM, по-видимому, совместно используют один общий ресурс
Я создаю утилиту WPF Tabbed Interface с использованием MVVM Light. В то время как автономные диалоговые окна живут в своем собственном .xaml
файлы, я понимаю, что для создания панелей интерфейса с вкладками, код для них должен находиться в DataTemplate
в моем MainWindow.xaml
,
Все работало нормально, пока мне не пришлось настраивать внешний вид DataGrid
, Я хотел вызвать обработчик событий при создании сетки, которая будет перебирать столбцы и выполнять определенные действия для определенных столбцов. Поэтому я добавил Initialized
обработчик события DataGrid
, Он вызывается только тогда, когда первая вкладка с DataGrid
создается... или когда я закрываю все вкладки и сначала открываю новую DataGrid
Вкладка. Еще немного расследования, и я обнаружил, что DataContextChanged
происходит всякий раз, когда я создаю последующую сетку или щелкаю между вкладками.
Я думаю, что я допустил недостаток дизайна, что, хотя для каждой сетки есть отдельная модель представления, существует только один общий ресурс сетки, но я не уверен, как это исправить.
Мой вопрос: как мне создать абсолютно отдельную сетку для каждой вкладки?
DataTemplate
из MainWindow.xaml:
<Window...>
<Window.Resources>
<DataTemplate DataType="{x:Type vm:GridViewModel}">
<Grid>
<DataGrid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0,0,0,32" RowHeight="{Binding RowHeight}" SelectionUnit="Cell"
IsReadOnly="True" LoadingRow="DataGrid_LoadingRow" ItemsSource="{Binding RecordSet}" AutoGenerateColumns="false"
Initialized="DataGrid_Initialized" DataContextChanged="DataGrid_DataContextChanged" >
</DataGrid>
</Grid>
</DataTemplate>
</Window.Resources>
</Window>
TabControl
изнутри Grid
из MainWindow.xml
<TabControl x:Name="DocumentArea" ItemsSource="{Binding Workspaces}" SelectedIndex="{Binding SelectedIndex}" HorizontalAlignment="Stretch" Margin="0,35,0,35" VerticalAlignment="Stretch">
<TabControl.ItemTemplate>
<DataTemplate>
<WrapPanel>
<TextBlock Text="{Binding Header}" />
<Button Command="{Binding CloseCommand}" Content="X" Margin="4,0,0,0" FontFamily="Courier New" Width="17" Height="17" VerticalContentAlignment="Center" />
</WrapPanel>
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
Пример метода в MainViewModel.cs, который создает Grid:
private void ShowAccountsGrid()
{
GridViewModel viewModel = new GridViewModel { Header = "QuickBooks Chart of Accounts" };
Workspaces.Add(viewModel);
SelectedIndex = Workspaces.IndexOf(viewModel);
viewModel.RecordSet = _quickBooksHelper.AccountList;
}
Соответствующий код из GridViewModel.cs:
public class GridViewModel : WorkspaceViewModel
{
private readonly IDataService _dataService;
public RelayCommand DoDeleteRow { get; set; }
public RelayCommand DoShowRowDetail { get; set; }
[PreferredConstructor]
public GridViewModel(IDataService dataService) :base()
{
InitBoundFields();
SetupRelayCommands();
_dataService = dataService;
_dataService.GetData(
(item, error) =>
{
if (error != null)
{
// Report error here
return;
}
});
}