我有三层深度的树状对象结构,并试图在DataGrid中表示它。
我将在下面展示XAML,但基本上有一个顶级DataGrid,其中DataGridTemplateColumn包含一个ToggleButton。如果单击该按钮,则会显示第二个DataGrid,它具有相同的设置。这应该允许您单击第二个网格中的ToggleButton并显示第三个(和最终的)DataGrid。
这是预期的结果:
因此,您点击“目的地...”以显示目标网格,然后点击“表达式...”以显示该详细信息。
两个按钮都使用相同的代码实现:
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ToggleButton Content="Destinations..." ButtonBase.Click="ToggleButton_Click" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
如果两个按钮都分配了它们的Click处理程序(相同的处理程序或不同),当我单击“Destinations ...”(在目标网格甚至显示之前)时,我得到一个NullReferenceException。
但是,如果我拿出“表达式...”按钮的处理程序,一切都只显示花花公子,但当然你无法扩展内部网格。
问题不在于我的对象,因为如果我只是离开网格的RowDetailsVisibilityMode =“可见”数据来自所有三个级别反映在网格中。这个问题似乎与在内部网格上使用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>
更新 我最初没有包含click处理程序的代码,因为那里不会发生异常。在调试时,我可以看到执行并返回有效行的Click(属于Destinations按钮)(并确认它是正确的行)。只要未分配内部按钮(表达式)的事件处理程序,该行就会扩展为花花公子。分配后,我收到错误。但请记住,表达式按钮永远不会被点击,我可以在调试器中确认处理程序只执行一次。
以下是点击处理程序的代码:
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;
}
答案 0 :(得分:3)
此link描述了您的问题。
简单地说,您无法附加到RowDetailsTemplate中内联的事件表单模板。
第一个解决方案:将模板移动到Control \ Window Resources:
<Window.Resources>
<ResourceDictionary>
<DataTemplate x:Key="innertemplate">
<ToggleButton Content="Expressions..." ButtonBase.Click="ToggleButton_Click" />
</DataTemplate>
<DataTemplate x:Key="template">
<StackPanel DockPanel.Dock="Left">
<Label Content="Add destination paths" />
<DataGrid ItemsSource="{Binding Destinations}" RowDetailsVisibilityMode="Visible">
<DataGrid.Columns>
<DataGridTemplateColumn CellTemplate="{StaticResource innertemplate}">
</DataGridTemplateColumn>
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DataGrid ItemsSource="{Binding Expressions}" AutoGenerateColumns="True">
</DataGrid>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
</StackPanel>
</DataTemplate>
</ResourceDictionary>
</Window.Resources>
并在网格中引用它:
RowDetailsTemplate="{StaticResource template}"
第二个解决方案:将模板内容移至UserControl并将模板添加为:
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<local:YourControl />
我的项目local
xmlns:local="clr-namespace:WpfApplication1"