0

我有一个三层深的树状对象结构,并试图在 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;
}
4

1 回答 1

3

链接描述了您的问题。

简单地说,您不能附加到在 RowDetailsTemplate 中内联的事件表单模板。

第一个解决方案:将您的模板移动到 Control\Window 资源:

 <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"

于 2012-07-17T09:33:04.673 回答