如何在WPF中修改DataGrid垂直滚动条的位置?

时间:2021-08-17 08:55:08

SOLVED: Please see my own answer below with the XAML code, a screenshot and an explanation.

已解决:请使用XAML代码,屏幕截图和说明查看下面我自己的答案。

It was a little tough to title this one, so let me explain what my issue is. I have a datagrid that has a defined height, so the scrollbar appears. I would like to contain the vertical scrollbar to the area that excludes the header. While it only scrolls the data rows and not the header, visually it covers the entire datagrid area to the right. The problem with that is that two boxes appear (one above and below) at the scrollbar area. I'm not sure how to get rid of them or how to contain the scrollbar to the body of the datagrid.

标题这一点有点难,所以让我解释一下我的问题。我有一个具有已定义高度的数据网格,因此会出现滚动条。我想将垂直滚动条包含到排除标题的区域。虽然它只滚动数据行而不是标题,但在视觉上它覆盖了右边的整个数据网格区域。问题在于滚动条区域出现两个框(一个在上方和下方)。我不知道如何摆脱它们或如何将滚动条包含到datagrid的主体。

如何在WPF中修改DataGrid垂直滚动条的位置?

The only thing I've been able to figure out (and I don't like the look of it) is to set the Background of the DataGrid to Transparent. Here's the outcome:

我唯一能够弄清楚的(我不喜欢它的外观)是将DataGrid的背景设置为透明。结果如下:

如何在WPF中修改DataGrid垂直滚动条的位置?

As you see, the scrollbar is sticking out annoyingly. Then, there's also the problem of a gap between the horizontal scrollbar and the last row if the background is transparent:

如你所见,滚动条令人讨厌。然后,如果背景是透明的,那么水平滚动条和最后一行之间也存在间隙的问题:

如何在WPF中修改DataGrid垂直滚动条的位置?

There's also a solution that gets rid of the background color of the datagrid for those two boxes, making them stand out less:

还有一个解决方案可以摆脱这两个盒子的数据网格的背景颜色,使它们更加突出:

http://social.msdn.microsoft.com/Forums/vstudio/en-US/9fc4252b-38b1-4369-8d76-b6c5ae1e4df5/how-to-remove-the-blank-space-above-the-verticalscroolbar-of-datagrid-in-wpf?forum=wpf

Similar solution can be found here: Annoying Square Where Scrollbars Meet

类似的解决方案可以在这里找到:恼人的广场滚动条相遇

However, it doesn't get rid of the problem that the scrollbar is awkwardly sticking out on the side.

但是,它并没有摆脱滚动条在侧面笨拙地伸出的问题。

Something I tested was to separate header from the body and place the body into a vertical ScrollViewer, then place the header and the body into a horizontal ScrollViewer so that they can be both scrolled horizontally. But, as you imagine, this doesn't work out well, because you have to scroll to the right to see the verticall scrollbar. I'm sure there's a way to make it so that it stays frozen on the right, but I haven't figured it out. Another issue is the fact the header width has to match the largest possible width of any cell in that column, or everything will be off. Here's the outcome shown when scrolled all the way to the right:

我测试的是将标题与正文分开并将正文放入垂直ScrollViewer,然后将标题和正文放入水平ScrollViewer中,以便它们可以水平滚动。但是,正如您想象的那样,这不会很好,因为您必须向右滚动才能看到verticall滚动条。我确信有一种方法可以让它在右边保持冷冻状态,但我还没弄清楚。另一个问题是标题宽度必须与该列中任何单元格的最大可能宽度相匹配,或者所有内容都将关闭。这是向右滚动时显示的结果:

如何在WPF中修改DataGrid垂直滚动条的位置?

I'm very new to control templates, so I can't figure out if this could work, because I can't find the right components:

我是新手来控制模板,所以我无法弄清楚这是否可行,因为我找不到合适的组件:

If I give the vertical scrollbar a negative margin to the left (say -6,0,0,0) and a similarly sized padding to the right of the cell block (0,0,6,0), the vertical scrollbar technically should move to the left. I will continue experimenting and try to figure this out, unless someone has the answer for me (which would be awesome).

如果我给垂直滚动条左边的一个负边距(比如-6,0,0,0)和一个类似大小的填充到单元格块的右边(0,0,6,0),垂直滚动条在技术上应该向左移动。我将继续尝试并尝试解决这个问题,除非有人为我提供答案(这将是非常棒的)。

EDIT #1:

Well, I made some progress and was able to set the margin of the scrollbar to (-17,0,0,0). 17 appears to be the width of the scrollbar. There appears to be a specific key for its width:

好吧,我取得了一些进展,并能够将滚动条的边距设置为(-17,0,0,0)。 17似乎是滚动条的宽度。它的宽度似乎有一个特定的键:

http://msdn.microsoft.com/en-us/library/system.windows.systemparameters.verticalscrollbarwidthkey(v=vs.110).aspx

but I can't figured out a way to insert that as the negative offset value in the margin within XAML. It wouldn't be hard to do it in code-behind.... but I'd rather keep it all XAML. Anyways, here's the screenshot of the progress and the XAML code portion:

但我无法想出一种方法来将其作为XAML中边距的负偏移值插入。在代码隐藏中做它并不难:但我宁愿把它全部保留在XAML中。无论如何,这里是进度的截图和XAML代码部分:

如何在WPF中修改DataGrid垂直滚动条的位置?

Here's XAML code portion:

这是XAML代码部分:

    <Style TargetType="{x:Type DataGrid}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type DataGrid}">
                    <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True">
                        <ScrollViewer x:Name="DG_ScrollViewer" Focusable="false">
                            <ScrollViewer.Template>
                                <ControlTemplate TargetType="{x:Type ScrollViewer}">
                                    <Grid>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="Auto"/>
                                            <ColumnDefinition Width="*"/>
                                            <ColumnDefinition Width="Auto"/>
                                        </Grid.ColumnDefinitions>
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="Auto"/>
                                            <RowDefinition Height="*"/>
                                            <RowDefinition Height="Auto"/>
                                        </Grid.RowDefinitions>
                                        <Button Command="{x:Static DataGrid.SelectAllCommand}" Focusable="false" Style="{DynamicResource {ComponentResourceKey ResourceId=DataGridSelectAllButtonStyle, TypeInTargetAssembly={x:Type DataGrid}}}" Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.All}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" Width="{Binding CellsPanelHorizontalOffset, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
                                        <DataGridColumnHeadersPresenter x:Name="PART_ColumnHeadersPresenter" Grid.Column="1" Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.Column}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
                                        <ScrollContentPresenter Margin="0,0,17,0" x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" Grid.ColumnSpan="2" Grid.Row="1"/>
                                        <ScrollBar Margin="-17,0,0,0" x:Name="PART_VerticalScrollBar" Grid.Column="2" Maximum="{TemplateBinding ScrollableHeight}" Orientation="Vertical" Grid.Row="1" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}"/>
                                        <Grid Grid.Column="1" Grid.Row="2">
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="{Binding NonFrozenColumnsViewportHorizontalOffset, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
                                                <ColumnDefinition Width="*"/>
                                            </Grid.ColumnDefinitions>
                                            <ScrollBar x:Name="PART_HorizontalScrollBar" Grid.Column="1" Maximum="{TemplateBinding ScrollableWidth}" Orientation="Horizontal" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportWidth}"/>
                                        </Grid>
                                    </Grid>
                                </ControlTemplate>
                            </ScrollViewer.Template>
                            <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        </ScrollViewer>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

The important part that makes the change possible is halfway through that code snippet where I set Margin="-17,0,0,0" for ScrollBar.

使更改成为可能的重要部分是在代码片段的中途,我为ScrollBar设置了Margin =“ - 17,0,0,0”。

My current problem is that I can't figure out which component to offset to the left by 17 (by adding either margin or padding). I've been messing with all of them and no luck thus far. I'll update as soon as I get it, unless someone figures it out before me. As it stands now, scrollbar will overlay anything in that last column until I fix the offset.

我目前的问题是我无法确定哪个组件向左偏移17(通过添加边距或填充)。到目前为止,我一直在弄乱他们所有人并且没有运气。我会在得到它后立即更新,除非有人在我之前说出来。就目前而言,滚动条将覆盖最后一列中的任何内容,直到我修复偏移量。

EDIT #2:

Please refer to the updated XAML code above. What I did was add Margin="0,0,17,0" to ScrollContentPresenter.

请参阅上面更新的XAML代码。我所做的是向ScrollContentPresenter添加Margin =“0,0,17,0”。

One side effect effect, which I can completely live with, is the fact that offsets the header as well, but you don't see that until you scroll all the way to the right. It effects only the header of the last column, because the ScrollContentPresenter offsets it as well... strangely, since there is a DataGridColumnHeadersPresenter, but it works independently... so, I'll keep on working on it. ScrollContentPresenter, unfortunately, doesn't have padding, which would work like a charm. So, now I have to figure out how I can pad it, rather than setting a margin, or figure out a different method.

一个副作用效果,我可以完全忍受,是一个事实,也抵消了标题,但你看不到,直到你一直向右滚动。它仅影响最后一列的标题,因为ScrollContentPresenter也将其偏移...奇怪的是,因为有一个DataGridColumnHeadersPresenter,但它独立工作......所以,我将继续处理它。不幸的是,ScrollContentPresenter没有填充,这就像魅力一样。所以,现在我必须弄清楚如何填充它,而不是设置边距,或找出不同的方法。

A similar method is to set the margin of the horizontal ScrollBar (that's the one in the second grid) to 0,0,-17,0. It'll move it 17 units to the right. Then, set the margin of DataGridColumnHeaderPresenter to 0,0,-17,0. It'll move it 17 units to the right.

类似的方法是将水平ScrollBar(即第二个网格中的一个)的边距设置为0,0,-17,0。它将向右移动17个单位。然后,将DataGridColumnHeaderPresenter的边距设置为0,0,-17,0。它将向右移动17个单位。

EDIT #3:

Here's another method for anyone that's interested:

对于任何有兴趣的人来说,这是另一种方法:

如何在WPF中修改DataGrid垂直滚动条的位置?

Set the margin of vertical ScrollBar to 0,-22,0,-17. -22 is the height of my headers, so adjust it to whatever yours are. This method stretches the scrollbar to cover the two white boxes.

将垂直ScrollBar的边距设置为0,-22,0,-17。 -22是我标题的高度,所以将其调整为你的标题。此方法拉伸滚动条以覆盖两个白色框。

EDIT #4:

I figured out the solution. Please see my answer for the XAML code, a screenshot and an explanation.

我想出了解决方案。请参阅我对XAML代码的回答,截图和解释。

2 个解决方案

#1


6  

So, above I've played around with several methods, but none of them achieved that perfect look and fill that I wanted. So, here's the solution that I'm very satisfied with. I hope that it helps others. I used Blend to go through every line of the template code and this is the best combination of things for my purpose.

所以,上面我已经玩了几种方法,但没有一种方法能达到我想要的完美外观和填充效果。所以,这是我非常满意的解决方案。我希望它能帮助别人。我使用Blend遍历模板代码的每一行,这是我的目的最好的组合。

Final result:

如何在WPF中修改DataGrid垂直滚动条的位置?

Pardon the messy headers, I covered them up on purpose. As you can see, the vertical scroll bar lines up nicely between the headers and the horizontal scroll bar located at the bottom. This was accomplished through setting margin of vertical ScrollBar (located in the first grid of the template) to -17 on the left side. Margin="-17,0,0,0". I then set the margin of ScrollContentProperty, located right above the vertical scroll bar within the template code, to 17 on the right side, Margin="0,0,17,0, to ensure that the vertical scroll bar doesn't cover any content. This leaves us with the header having 17 units of empty space to the right when we scroll to the extreme right, and that's due to the fact that our 17 margin on ScrollContentPresenter effects the header as well. To counter that, I created a style for DataGridColumnHeader and set its margin to -17 on the right side, Margin="0,0,-17,0", ensuring that it bleeds over into the empty space. To ensure that the last column header text is not hovering over the vertical scroll bar, making it visually unappealing, I added a padding of 17 to the right side, Padding="0,0,17,0".

原谅凌乱的标题,我故意掩盖它们。如您所见,垂直滚动条在标题和位于底部的水平滚动条之间很好地排列。这是通过将垂直ScrollBar(位于模板的第一个网格中)的边距设置为左侧的-17来完成的。保证金= “ - 17,0,0,0”。然后我将位于模板代码中垂直滚动条正上方的ScrollContentProperty的边距设置为右侧的17,Margin =“0,0,17,0,以确保垂直滚动条不覆盖任何当我们滚动到最右边时,这会让我们看到右边有17个单位空格的标题,这是因为我们在ScrollContentPresenter上的17个边距也会影响标题。为了解决这个问题,我创建了一个DataGridColumnHeader的样式,并在右侧将边距设置为-17,Margin =“0,0,-17,0”,确保它渗透到空白区域。确保最后一列标题文本不会悬停在垂直滚动条,使它在视觉上没有吸引力,我在右侧添加了17的填充,Padding =“0,0,17,0”。

Here's my XAML code for the DataGrid and DataGridColumnHeader that made this possible:

这是我的DataGrid和DataGridColumnHeader的XAML代码,它使这成为可能:

DataGrid:

    <Style TargetType="{x:Type DataGrid}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type DataGrid}">
                    <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True">
                        <ScrollViewer x:Name="DG_ScrollViewer" Focusable="false">
                            <ScrollViewer.Template>
                                <ControlTemplate TargetType="{x:Type ScrollViewer}">
                                    <Grid>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="Auto"/>
                                            <ColumnDefinition Width="*"/>
                                            <ColumnDefinition Width="Auto"/>
                                        </Grid.ColumnDefinitions>
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="Auto"/>
                                            <RowDefinition Height="*"/>
                                            <RowDefinition Height="Auto"/>
                                        </Grid.RowDefinitions>
                                        <Button Command="{x:Static DataGrid.SelectAllCommand}" Focusable="false" Style="{DynamicResource {ComponentResourceKey ResourceId=DataGridSelectAllButtonStyle, TypeInTargetAssembly={x:Type DataGrid}}}" Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.All}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" Width="{Binding CellsPanelHorizontalOffset, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
                                        <DataGridColumnHeadersPresenter x:Name="PART_ColumnHeadersPresenter" Grid.Column="1" Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.Column}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
                                        <!--This is the scroll content presenter that gets shifted to the left 17 units so that scrollbar doesn't cover it-->
                                        <ScrollContentPresenter Margin="0,0,17,0" x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" Grid.ColumnSpan="2" Grid.Row="1"/>
                                        <!--This is the vertical scrollbar. Margin is used to shift it to the left 17 units over the content-->
                                        <ScrollBar Margin="-17,0,0,0" x:Name="PART_VerticalScrollBar" Grid.Column="2" Maximum="{TemplateBinding ScrollableHeight}" Orientation="Vertical" Grid.Row="1" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}"/>
                                        <Grid Grid.Column="1" Grid.Row="2">
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="{Binding NonFrozenColumnsViewportHorizontalOffset, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
                                                <ColumnDefinition Width="*"/>
                                            </Grid.ColumnDefinitions>
                                            <ScrollBar x:Name="PART_HorizontalScrollBar" Grid.Column="1" Maximum="{TemplateBinding ScrollableWidth}" Orientation="Horizontal" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportWidth}"/>
                                        </Grid>
                                    </Grid>
                                </ControlTemplate>
                            </ScrollViewer.Template>
                            <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        </ScrollViewer>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

DataGridColumnHeader:

    <Style TargetType="{x:Type DataGridColumnHeader}">
        <Setter Property="Height" Value="22"/>
        <!--Padding to shift header text of the last column to the left 17 units-->
        <Setter Property="Padding" Value="0,0,17,0"/>
        <!--Margin to shift the entire header to the right 17 units to fill the void-->
        <Setter Property="Margin" Value="0,0,-17,0"/>
    </Style>

A similar method would be to set margin of the horizontal scroll bar to -17, Margin="0,0,-17,0", set padding of DataGridColumnHeader to 17, Padding="0,0,17,0", and its margin to -17, Margin="0,0,-17,0". This achieves the same result.

类似的方法是将水平滚动条的边距设置为-17,Margin =“0,0,-17,0”,将DataGridColumnHeader的填充设置为17,Padding =“0,0,17,0”,以及其保证金为-17,保证金=“0,0,-17,0”。这实现了相同的结果。

#2


1  

Better solution is set up Grid.Row="0" Grid.RowSpan="2" for Name="PART_VerticalScrollBar"

更好的解决方案是建立Grid.Row =“0”Grid.RowSpan =“2”for Name =“PART_VerticalScrollBar”

#1


6  

So, above I've played around with several methods, but none of them achieved that perfect look and fill that I wanted. So, here's the solution that I'm very satisfied with. I hope that it helps others. I used Blend to go through every line of the template code and this is the best combination of things for my purpose.

所以,上面我已经玩了几种方法,但没有一种方法能达到我想要的完美外观和填充效果。所以,这是我非常满意的解决方案。我希望它能帮助别人。我使用Blend遍历模板代码的每一行,这是我的目的最好的组合。

Final result:

如何在WPF中修改DataGrid垂直滚动条的位置?

Pardon the messy headers, I covered them up on purpose. As you can see, the vertical scroll bar lines up nicely between the headers and the horizontal scroll bar located at the bottom. This was accomplished through setting margin of vertical ScrollBar (located in the first grid of the template) to -17 on the left side. Margin="-17,0,0,0". I then set the margin of ScrollContentProperty, located right above the vertical scroll bar within the template code, to 17 on the right side, Margin="0,0,17,0, to ensure that the vertical scroll bar doesn't cover any content. This leaves us with the header having 17 units of empty space to the right when we scroll to the extreme right, and that's due to the fact that our 17 margin on ScrollContentPresenter effects the header as well. To counter that, I created a style for DataGridColumnHeader and set its margin to -17 on the right side, Margin="0,0,-17,0", ensuring that it bleeds over into the empty space. To ensure that the last column header text is not hovering over the vertical scroll bar, making it visually unappealing, I added a padding of 17 to the right side, Padding="0,0,17,0".

原谅凌乱的标题,我故意掩盖它们。如您所见,垂直滚动条在标题和位于底部的水平滚动条之间很好地排列。这是通过将垂直ScrollBar(位于模板的第一个网格中)的边距设置为左侧的-17来完成的。保证金= “ - 17,0,0,0”。然后我将位于模板代码中垂直滚动条正上方的ScrollContentProperty的边距设置为右侧的17,Margin =“0,0,17,0,以确保垂直滚动条不覆盖任何当我们滚动到最右边时,这会让我们看到右边有17个单位空格的标题,这是因为我们在ScrollContentPresenter上的17个边距也会影响标题。为了解决这个问题,我创建了一个DataGridColumnHeader的样式,并在右侧将边距设置为-17,Margin =“0,0,-17,0”,确保它渗透到空白区域。确保最后一列标题文本不会悬停在垂直滚动条,使它在视觉上没有吸引力,我在右侧添加了17的填充,Padding =“0,0,17,0”。

Here's my XAML code for the DataGrid and DataGridColumnHeader that made this possible:

这是我的DataGrid和DataGridColumnHeader的XAML代码,它使这成为可能:

DataGrid:

    <Style TargetType="{x:Type DataGrid}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type DataGrid}">
                    <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True">
                        <ScrollViewer x:Name="DG_ScrollViewer" Focusable="false">
                            <ScrollViewer.Template>
                                <ControlTemplate TargetType="{x:Type ScrollViewer}">
                                    <Grid>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="Auto"/>
                                            <ColumnDefinition Width="*"/>
                                            <ColumnDefinition Width="Auto"/>
                                        </Grid.ColumnDefinitions>
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="Auto"/>
                                            <RowDefinition Height="*"/>
                                            <RowDefinition Height="Auto"/>
                                        </Grid.RowDefinitions>
                                        <Button Command="{x:Static DataGrid.SelectAllCommand}" Focusable="false" Style="{DynamicResource {ComponentResourceKey ResourceId=DataGridSelectAllButtonStyle, TypeInTargetAssembly={x:Type DataGrid}}}" Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.All}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" Width="{Binding CellsPanelHorizontalOffset, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
                                        <DataGridColumnHeadersPresenter x:Name="PART_ColumnHeadersPresenter" Grid.Column="1" Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.Column}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
                                        <!--This is the scroll content presenter that gets shifted to the left 17 units so that scrollbar doesn't cover it-->
                                        <ScrollContentPresenter Margin="0,0,17,0" x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" Grid.ColumnSpan="2" Grid.Row="1"/>
                                        <!--This is the vertical scrollbar. Margin is used to shift it to the left 17 units over the content-->
                                        <ScrollBar Margin="-17,0,0,0" x:Name="PART_VerticalScrollBar" Grid.Column="2" Maximum="{TemplateBinding ScrollableHeight}" Orientation="Vertical" Grid.Row="1" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}"/>
                                        <Grid Grid.Column="1" Grid.Row="2">
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="{Binding NonFrozenColumnsViewportHorizontalOffset, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
                                                <ColumnDefinition Width="*"/>
                                            </Grid.ColumnDefinitions>
                                            <ScrollBar x:Name="PART_HorizontalScrollBar" Grid.Column="1" Maximum="{TemplateBinding ScrollableWidth}" Orientation="Horizontal" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportWidth}"/>
                                        </Grid>
                                    </Grid>
                                </ControlTemplate>
                            </ScrollViewer.Template>
                            <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        </ScrollViewer>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

DataGridColumnHeader:

    <Style TargetType="{x:Type DataGridColumnHeader}">
        <Setter Property="Height" Value="22"/>
        <!--Padding to shift header text of the last column to the left 17 units-->
        <Setter Property="Padding" Value="0,0,17,0"/>
        <!--Margin to shift the entire header to the right 17 units to fill the void-->
        <Setter Property="Margin" Value="0,0,-17,0"/>
    </Style>

A similar method would be to set margin of the horizontal scroll bar to -17, Margin="0,0,-17,0", set padding of DataGridColumnHeader to 17, Padding="0,0,17,0", and its margin to -17, Margin="0,0,-17,0". This achieves the same result.

类似的方法是将水平滚动条的边距设置为-17,Margin =“0,0,-17,0”,将DataGridColumnHeader的填充设置为17,Padding =“0,0,17,0”,以及其保证金为-17,保证金=“0,0,-17,0”。这实现了相同的结果。

#2


1  

Better solution is set up Grid.Row="0" Grid.RowSpan="2" for Name="PART_VerticalScrollBar"

更好的解决方案是建立Grid.Row =“0”Grid.RowSpan =“2”for Name =“PART_VerticalScrollBar”