C# MVVM选项卡式界面面板似乎共享一个公共资源
我正在使用MVVM Light创建一个WPF选项卡式界面实用程序。虽然独立对话框存在于它们自己的C# MVVM选项卡式界面面板似乎共享一个公共资源,c#,wpf,mvvm-light,tabbed-interface,C#,Wpf,Mvvm Light,Tabbed Interface,我正在使用MVVM Light创建一个WPF选项卡式界面实用程序。虽然独立对话框存在于它们自己的.xaml文件中,但我的理解是,要创建选项卡式界面面板,这些对话框的代码应该位于我的MainWindow.xaml中的DataTemplate中 在我需要定制DataGrid的外观之前,一切都很正常。我想要的是在创建网格时调用事件处理程序,该网格将遍历列并对某些列执行一些自定义操作。因此,我添加了一个初始化的事件处理程序到数据网格。只有在创建第一个带有DataGrid的选项卡时,才会调用它。。。或者当
.xaml
文件中,但我的理解是,要创建选项卡式界面面板,这些对话框的代码应该位于我的MainWindow.xaml
中的DataTemplate
中
在我需要定制DataGrid
的外观之前,一切都很正常。我想要的是在创建网格时调用事件处理程序,该网格将遍历列并对某些列执行一些自定义操作。因此,我添加了一个初始化的
事件处理程序到数据网格
。只有在创建第一个带有DataGrid
的选项卡时,才会调用它。。。或者当我关闭所有选项卡并打开新的第一个DataGrid
选项卡时。再调查一下,我发现每当我创建后续网格或在选项卡之间单击时,DataContextChanged
就会发生
我认为我犯了一个设计缺陷,即虽然每个网格都有一个单独的视图模型,但只有一个通用的网格资源,但我不确定如何纠正它
我的问题:如何为每个选项卡创建一个完全独立的网格
DataTemplate
来自main window.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>
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;
}
});
}
MainViewModel.cs中创建网格的方法示例:
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的相关代码:
<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>
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;
}
});
}
从我看到的代码没有问题,您必须在MainWindow.XAML中显示使用该模板的其余XAML。需要指出的是,使用代码隐藏(
Initialized
,DataContextChanged
等)意味着这不是MVVM,这很可能是问题的根源。顺便说一句,这种性质的问题通常通过将x:Shared=“False”
放在DataTemplate标记中来解决。但同样,它通常是一个解决根本问题的创可贴解决方案。main窗口中没有其他XAML引用此DataTemplate
。您的评论表明我缺少一些关键的MVVM概念;这是我第一次尝试使用它。我将进行一些学习,希望这能使我的编码错误更加明显。您发布的代码来自您的窗口。参考资料块,但参考资料本身不显示任何内容。您的XAML中必须有其他引用该DataTemple的内容,否则您根本看不到网格。在这种情况下,引用将是隐式的,因为您的数据模板使用的是数据类型而不是键,但它仍然存在。实际使用该模板的代码的XAML是什么?您所说的“选项卡式界面”是什么意思?您正在使用TabControl吗?请发布您的XAML标记。