我正在使用 MVVM Light 创建一个 WPF 选项卡式界面实用程序。虽然独立对话框存在于它们自己的.xaml
文件中,但我的理解是,要创建选项卡式界面面板,它们的代码应该位于DataTemplate
我的MainWindow.xaml
.
在我需要自定义DataGrid
. 我想要的是在创建网格时调用事件处理程序,该网格将遍历列并为某些列执行一些自定义操作。所以我Initialized
在DataGrid
. 只有在DataGrid
创建第一个带有 a 的选项卡时才会调用它......或者当我关闭所有选项卡并打开一个新的第一个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;
}
});
}