WPF DataGrid Row 扩展行详细信息后不调整高度

发布于 2024-12-04 00:21:31 字数 10015 浏览 0 评论 0原文

我有一个带有分层数据的数据网格。每当我折叠行详细信息时,父行不会自动调整大小。这最终意味着,当我不断扩展“行详细信息”时,父网格将继续占用越来越多的空间,直到我折叠同一级别的行。我窥探了应用程序,发现保持新高度的最低级别元素是 DataGridRowsPresenter,即 PART_ColumnHeadersPresenter。

我有自己的行和网格控制模板:

<Style x:Key="{x:Type Custom:DataGrid}" TargetType="{x:Type Custom:DataGrid}">
        <Setter Property="CanUserResizeRows" Value="False" />
        <Setter Property="Background"
            Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
        <Setter Property="Foreground"
            Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="BorderBrush" Value="#FF688CAF" />
        <Setter Property="BorderThickness" Value="1" />
        <!-- This is needed to force DG to have a non-default value.  Otherwise the DGR.DetailsVisibility cannot have a value of VisibleWhenSelected by default. -->
        <Setter Property="RowDetailsVisibilityMode" Value="VisibleWhenSelected" />
        <Setter Property="ScrollViewer.CanContentScroll"
            Value="true"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Custom:DataGrid}">
                    <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        SnapsToDevicePixels="True"
                        Padding="{TemplateBinding Padding}">
                        <ScrollViewer Focusable="false"
                                  Name="DG_ScrollViewer">
                            <ScrollViewer.Template>
                                <ControlTemplate TargetType="{x:Type ScrollViewer}">
                                    <Grid>
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="Auto"/>
                                            <RowDefinition Height="*"/>
                                            <RowDefinition Height="Auto"/>
                                        </Grid.RowDefinitions>

                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="Auto"/>
                                            <ColumnDefinition Width="*"/>
                                            <ColumnDefinition Width="Auto"/>
                                        </Grid.ColumnDefinitions>

                                        <!--Left Column Header Corner -->
                                        <Button Command="{x:Static Custom:DataGrid.SelectAllCommand}"
                                            Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type Custom:DataGrid}}, Path=CellsPanelHorizontalOffset}"
                                            Template="{StaticResource SelectAllButtonTemplate}"
                                            Focusable="false"
                                            Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type Custom:DataGrid}}, Path=HeadersVisibility, Converter={x:Static Custom:DataGrid.HeadersVisibilityConverter}, ConverterParameter={x:Static Custom:DataGridHeadersVisibility.All}}" />

                                        <!--Column Headers-->
                                        <Custom:DataGridColumnHeadersPresenter Grid.Column="1" 
                                                   Name="PART_ColumnHeadersPresenter"
                                                   Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type Custom:DataGrid}}, Path=HeadersVisibility, Converter={x:Static Custom:DataGrid.HeadersVisibilityConverter}, ConverterParameter={x:Static Custom:DataGridHeadersVisibility.Column}}"/>

                                        <!--DataGrid content-->
                                        <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" 
                                                                Grid.Row="1" 
                                                                Grid.ColumnSpan="2" 
                                                                CanContentScroll="{TemplateBinding CanContentScroll}"
                                                                Height="Auto" VerticalAlignment="Stretch">


                                        </ScrollContentPresenter>

                                        <ScrollBar Grid.Row="1" Grid.Column="2" Name="PART_VerticalScrollBar"
                                         Orientation="Vertical"
                                         Maximum="{TemplateBinding ScrollableHeight}"
                                         ViewportSize="{TemplateBinding ViewportHeight}"
                                         Value="{Binding Path=VerticalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
                                         Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"/>
                                        <Grid Grid.Row="2" Grid.Column="1">
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type Custom:DataGrid}}, Path=NonFrozenColumnsViewportHorizontalOffset}"/>
                                                <ColumnDefinition Width="*"/>
                                            </Grid.ColumnDefinitions>
                                            <ScrollBar Grid.Column="1"
                                                   Name="PART_HorizontalScrollBar"
                                                   Orientation="Horizontal"
                                                   Maximum="{TemplateBinding ScrollableWidth}"
                                                   ViewportSize="{TemplateBinding ViewportWidth}"
                                                   Value="{Binding Path=HorizontalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
                                                   Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/>
                                        </Grid>
                                    </Grid>
                                </ControlTemplate>
                            </ScrollViewer.Template>
                            <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                        </ScrollViewer>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="IsGrouping" Value="true">
                <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
            </Trigger>
        </Style.Triggers>
    </Style>

<ControlTemplate x:Key="PlainDataGridRowControlTemplate" TargetType="{x:Type Custom:DataGridRow}">
        <Grid x:Name="LayoutRoot">
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <Grid x:Name="DGR_Border" 
                Background="Transparent"
                SnapsToDevicePixels="True">
                <Custom:SelectiveScrollingGrid Name="DGR_SelectiveScrollingGrid">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>

                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>

                    <Custom:DataGridCellsPresenter Grid.Column="1" Name="DGR_CellsPresenter" ItemsPanel="{TemplateBinding ItemsPanel}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    <Custom:DataGridDetailsPresenter Height="Auto" 
                                                          Grid.Column="1" 
                                                          Grid.Row="1" 
                                                          Visibility="{TemplateBinding DetailsVisibility}" Custom:SelectiveScrollingGrid.SelectiveScrollingOrientation="{Binding RelativeSource={RelativeSource AncestorType={x:Type Custom:DataGrid}}, Path=AreRowDetailsFrozen, Converter={x:Static Custom:DataGrid.RowDetailsScrollingConverter}, ConverterParameter={x:Static Custom:SelectiveScrollingOrientation.Vertical}}" />
                    <!--<localprimitives:DataGridRowHeader localprimitives:SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical" Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:DataGrid}}, Path=HeadersVisibility, Converter={x:Static local:DataGrid.HeadersVisibilityConverter}, ConverterParameter={x:Static local:DataGridHeadersVisibility.Row}}"/>-->
                    <Custom:DataGridRowHeader Grid.RowSpan="2" Custom:SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical" />
                </Custom:SelectiveScrollingGrid>
            </Grid>
        </Grid>
    </ControlTemplate>
    <Style TargetType="Custom:DataGridRow">
        <Setter Property="Margin" Value="0, 0, 0, 0"/>
        <Setter Property="Template" Value="{StaticResource PlainDataGridRowControlTemplate}" />
    </Style>

有人可以建议吗?

I have a DataGrid with Hierarchical Data. Whenever I collapse my Row Details the Parent Row doesn't resize automatically. This ultimately means that as I keep expanding my Row Details the Parent Grid keeps on taking more and more space until I collapse a row at the same level. I snooped the Application and found out that the lowest level element that keeps the new height is the DataGridRowsPresenter which is the PART_ColumnHeadersPresenter.

I have my own ControlTemplate for the Row and the Grid:

<Style x:Key="{x:Type Custom:DataGrid}" TargetType="{x:Type Custom:DataGrid}">
        <Setter Property="CanUserResizeRows" Value="False" />
        <Setter Property="Background"
            Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
        <Setter Property="Foreground"
            Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="BorderBrush" Value="#FF688CAF" />
        <Setter Property="BorderThickness" Value="1" />
        <!-- This is needed to force DG to have a non-default value.  Otherwise the DGR.DetailsVisibility cannot have a value of VisibleWhenSelected by default. -->
        <Setter Property="RowDetailsVisibilityMode" Value="VisibleWhenSelected" />
        <Setter Property="ScrollViewer.CanContentScroll"
            Value="true"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Custom:DataGrid}">
                    <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        SnapsToDevicePixels="True"
                        Padding="{TemplateBinding Padding}">
                        <ScrollViewer Focusable="false"
                                  Name="DG_ScrollViewer">
                            <ScrollViewer.Template>
                                <ControlTemplate TargetType="{x:Type ScrollViewer}">
                                    <Grid>
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="Auto"/>
                                            <RowDefinition Height="*"/>
                                            <RowDefinition Height="Auto"/>
                                        </Grid.RowDefinitions>

                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="Auto"/>
                                            <ColumnDefinition Width="*"/>
                                            <ColumnDefinition Width="Auto"/>
                                        </Grid.ColumnDefinitions>

                                        <!--Left Column Header Corner -->
                                        <Button Command="{x:Static Custom:DataGrid.SelectAllCommand}"
                                            Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type Custom:DataGrid}}, Path=CellsPanelHorizontalOffset}"
                                            Template="{StaticResource SelectAllButtonTemplate}"
                                            Focusable="false"
                                            Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type Custom:DataGrid}}, Path=HeadersVisibility, Converter={x:Static Custom:DataGrid.HeadersVisibilityConverter}, ConverterParameter={x:Static Custom:DataGridHeadersVisibility.All}}" />

                                        <!--Column Headers-->
                                        <Custom:DataGridColumnHeadersPresenter Grid.Column="1" 
                                                   Name="PART_ColumnHeadersPresenter"
                                                   Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type Custom:DataGrid}}, Path=HeadersVisibility, Converter={x:Static Custom:DataGrid.HeadersVisibilityConverter}, ConverterParameter={x:Static Custom:DataGridHeadersVisibility.Column}}"/>

                                        <!--DataGrid content-->
                                        <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" 
                                                                Grid.Row="1" 
                                                                Grid.ColumnSpan="2" 
                                                                CanContentScroll="{TemplateBinding CanContentScroll}"
                                                                Height="Auto" VerticalAlignment="Stretch">


                                        </ScrollContentPresenter>

                                        <ScrollBar Grid.Row="1" Grid.Column="2" Name="PART_VerticalScrollBar"
                                         Orientation="Vertical"
                                         Maximum="{TemplateBinding ScrollableHeight}"
                                         ViewportSize="{TemplateBinding ViewportHeight}"
                                         Value="{Binding Path=VerticalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
                                         Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"/>
                                        <Grid Grid.Row="2" Grid.Column="1">
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type Custom:DataGrid}}, Path=NonFrozenColumnsViewportHorizontalOffset}"/>
                                                <ColumnDefinition Width="*"/>
                                            </Grid.ColumnDefinitions>
                                            <ScrollBar Grid.Column="1"
                                                   Name="PART_HorizontalScrollBar"
                                                   Orientation="Horizontal"
                                                   Maximum="{TemplateBinding ScrollableWidth}"
                                                   ViewportSize="{TemplateBinding ViewportWidth}"
                                                   Value="{Binding Path=HorizontalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
                                                   Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/>
                                        </Grid>
                                    </Grid>
                                </ControlTemplate>
                            </ScrollViewer.Template>
                            <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                        </ScrollViewer>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="IsGrouping" Value="true">
                <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
            </Trigger>
        </Style.Triggers>
    </Style>

<ControlTemplate x:Key="PlainDataGridRowControlTemplate" TargetType="{x:Type Custom:DataGridRow}">
        <Grid x:Name="LayoutRoot">
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <Grid x:Name="DGR_Border" 
                Background="Transparent"
                SnapsToDevicePixels="True">
                <Custom:SelectiveScrollingGrid Name="DGR_SelectiveScrollingGrid">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>

                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>

                    <Custom:DataGridCellsPresenter Grid.Column="1" Name="DGR_CellsPresenter" ItemsPanel="{TemplateBinding ItemsPanel}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    <Custom:DataGridDetailsPresenter Height="Auto" 
                                                          Grid.Column="1" 
                                                          Grid.Row="1" 
                                                          Visibility="{TemplateBinding DetailsVisibility}" Custom:SelectiveScrollingGrid.SelectiveScrollingOrientation="{Binding RelativeSource={RelativeSource AncestorType={x:Type Custom:DataGrid}}, Path=AreRowDetailsFrozen, Converter={x:Static Custom:DataGrid.RowDetailsScrollingConverter}, ConverterParameter={x:Static Custom:SelectiveScrollingOrientation.Vertical}}" />
                    <!--<localprimitives:DataGridRowHeader localprimitives:SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical" Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:DataGrid}}, Path=HeadersVisibility, Converter={x:Static local:DataGrid.HeadersVisibilityConverter}, ConverterParameter={x:Static local:DataGridHeadersVisibility.Row}}"/>-->
                    <Custom:DataGridRowHeader Grid.RowSpan="2" Custom:SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical" />
                </Custom:SelectiveScrollingGrid>
            </Grid>
        </Grid>
    </ControlTemplate>
    <Style TargetType="Custom:DataGridRow">
        <Setter Property="Margin" Value="0, 0, 0, 0"/>
        <Setter Property="Template" Value="{StaticResource PlainDataGridRowControlTemplate}" />
    </Style>

Can someone please advise?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

千紇 2024-12-11 00:21:31

我通过在 DataGrid-Style 中使用此设置器解决了这个问题:

但不要问我为什么这适用于此二传手。

I solved this issue by using this setter within my DataGrid-Style:

<Setter Property="ScrollViewer.CanContentScroll" Value="False" />

But don't ask me why this works with this setter.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文