我有一个三层深的树状对象结构,并试图在 DataGrid 中表示它。
我将在下面展示 XAML,但基本上有一个顶级 DataGrid,其 DataGridTemplateColumn 包含一个 ToggleButton。如果单击该按钮,它将显示第二个 DataGrid,它具有相同的设置。这应该允许您单击第二个网格中的 ToggleButton 并显示第三个(也是最后一个)DataGrid。
这是预期的结果:
因此,您可以单击“目的地...”以显示“目的地”网格,然后单击“表达式...”以显示该详细信息。
两个按钮都使用相同的代码实现:
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ToggleButton Content="Destinations..." ButtonBase.Click="ToggleButton_Click" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
如果两个按钮都分配了它们的 Click 处理程序(相同的处理程序或不同的处理程序),当我单击“目的地...”时(甚至在目的地网格显示之前),我会收到 NullReferenceException。
但是如果我取出“Expressions...”按钮的处理程序,一切都显示得很好,但当然你不能扩展内部网格。
问题不在于我的对象,因为如果我只是离开网格的 RowDetailsVisibilityMode="Visible" 来自所有三个级别的数据都会反映在网格中。该问题似乎与使用内部网格上的 ButtonBase.Click 事件有关。
这是 XAML:
<Window x:Class="SPConvert.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Stored Procedure Converter" Height="425" Width="705">
<Grid>
<DataGrid Name="conversionsGrid" RowDetailsVisibilityMode="Collapsed" CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ToggleButton Content="Destinations..." ButtonBase.Click="ToggleButton_Click" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<StackPanel DockPanel.Dock="Left">
<Label Content="Add destination paths" />
<DataGrid ItemsSource="{Binding Destinations}" RowDetailsVisibilityMode="Visible">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ToggleButton Content="Expressions..." ButtonBase.Click="ToggleButton_Click" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DataGrid ItemsSource="{Binding Expressions}" AutoGenerateColumns="True">
</DataGrid>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
</StackPanel>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
</Grid>
</Window>
更新: 我最初没有包含点击处理程序的代码,因为那里没有发生异常。调试时,我可以看到单击(目的地按钮)执行并返回一个有效行(并确认它是正确的行)。只要未分配内部按钮(表达式)的事件处理程序,该行就会扩展得很好。当它被分配时,我得到了错误。但请记住,永远不会单击“表达式”按钮,我可以在调试器中确认处理程序只执行一次。
这是点击处理程序的代码:
private DataGridRow FindClickedRow(DependencyObject dep)
{
// dep is the DependencyObject that was clicked. We can then iterate up the visual tree to find the clicked row.
while ((dep != null) && !(dep is DataGridRow))
dep = VisualTreeHelper.GetParent(dep);
return dep as DataGridRow;
}
private void ToggleButton_Click(object sender, RoutedEventArgs e)
{
DataGridRow row = FindClickedRow(e.OriginalSource as DependencyObject);
row.DetailsVisibility = (row.DetailsVisibility == Visibility.Collapsed)?Visibility.Visible:Visibility.Collapsed;
}