0

3 レベルの深さのツリー状のオブジェクト構造があり、それを DataGrid で表現しようとしました。

以下に XAML を示しますが、基本的には最上位の DataGrid と、ToggleButton を含む DataGridTemplateColumn があります。ボタンをクリックすると、同じ設定を持つ 2 番目の DataGrid が表示されます。これにより、2 番目のグリッドの ToggleButton をクリックして、3 番目 (および最終) の DataGrid を表示できるようになります。

これは期待される結果です:

ここに画像の説明を入力

したがって、[宛先...] をクリックして宛先グリッドを表示し、[式...] をクリックしてその詳細を表示します。

どちらのボタンも同じコードで実装されています。

<DataGridTemplateColumn>
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <ToggleButton Content="Destinations..." ButtonBase.Click="ToggleButton_Click" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

両方のボタンに Click ハンドラーが割り当てられている場合 (同じハンドラー、または異なるハンドラー)、"Destinations..." をクリックすると (宛先グリッドが表示される前に) NullReferenceException が発生します。

しかし、「式...」ボタンのハンドラーを取り出すと、すべてがうまく表示されますが、もちろん内側のグリッドを展開することはできません。

グリッドの RowDetailsVisibilityMode="Visible" をそのままにしておくと、3 つのレベルすべてのデータがグリッドに反映されるため、問題はオブジェクトにはありません。この問題は、内部グリッドでの 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>

更新: 例外がそこで発生しないため、最初はクリック ハンドラーのコードを含めませんでした。デバッグ時に、(Destinations ボタンの) クリックが実行され、有効な行が返されるのを確認できます (そして、それが正しい行であることを確認します)。内側のボタン (式) のイベント ハンドラーが割り当てられていない限り、行はダンディに展開されます。それが割り当てられると、エラーが発生します。ただし、[式] ボタンがクリックされることはなく、ハンドラが 1 回しか実行されないことをデバッガで確認できることに注意してください。

クリック ハンドラのコードは次のとおりです。

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

2番目の解決策:テンプレートのコンテンツをUserControlに移動し、次のようにテンプレートを追加します。

 <DataGrid.RowDetailsTemplate>
            <DataTemplate>
                <local:YourControl />

local私のプロジェクトはどこにありますかxmlns:local="clr-namespace:WpfApplication1"

于 2012-07-17T09:33:04.673 に答える