问题
I have a layout problem with a datagrid in my C# WPF application. If the content of my datagrid can't be displayed in my datagrid because there are to many rows, a scrollviewer (and scrollbar) is displayed. This is the correct way and I'm happy about it.
The problem is, that the position of the scrollviewer in my datagrid ist wrong. The scrollviewer starts in the header row, but the Scrollbar is displayed in the first row of my content. In the header there is a white retangle. This is because the background of my datagrid is white. But the background of my header is gray.
I uploaded a picture with a red arrow to clarify my problem. The white retangle looks really ugly, so in my opinion it's the better way to change the position of the scrollviewer, so it starts in the first row of the content. Maybe there is another possibility to solve the problem?
"Datagrid with Scrollviewer"-Image:

Thanks for any hints, which will help me to solve the problem!
Best regards, Flasher
回答1:
you can make your own style for your datagrid, here is a style made with blend with two changes
look at these two changes
for PART_VerticalScrollBar
-> Grid.Row="0"
and Grid.RowSpan="2"
and for the grid that holds the PART_HorizontalScrollBar
-> Grid.ColumnSpan="2"
here is the complete style
<Style x:Key="myGridStyle"
TargetType="{x:Type Controls:DataGrid}">
<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" />
<Setter Property="RowDetailsVisibilityMode"
Value="VisibleWhenSelected" />
<Setter Property="ScrollViewer.CanContentScroll"
Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Controls:DataGrid}">
<Border SnapsToDevicePixels="True"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}">
<ScrollViewer x:Name="DG_ScrollViewer"
Focusable="False">
<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>
<Button Width="{Binding CellsPanelHorizontalOffset, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type Controls:DataGrid}}}"
Focusable="False">
<Button.Visibility>
<Binding Path="HeadersVisibility"
RelativeSource="{RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type Controls:DataGrid}}">
<Binding.ConverterParameter>
<Controls:DataGridHeadersVisibility>All</Controls:DataGridHeadersVisibility>
</Binding.ConverterParameter>
</Binding>
</Button.Visibility>
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Rectangle x:Name="Border"
Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
SnapsToDevicePixels="True" />
<Polygon x:Name="Arrow"
Fill="Black"
Stretch="Uniform"
HorizontalAlignment="Right"
Margin="8,8,3,3"
VerticalAlignment="Bottom"
Opacity="0.15"
Points="0,10 10,10 10,0" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter Property="Stroke"
TargetName="Border"
Value="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" />
</Trigger>
<Trigger Property="IsPressed"
Value="True">
<Setter Property="Fill"
TargetName="Border"
Value="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" />
</Trigger>
<Trigger Property="IsEnabled"
Value="False">
<Setter Property="Visibility"
TargetName="Arrow"
Value="Collapsed" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
<Button.Command>
<RoutedCommand />
</Button.Command>
</Button>
<Custom:DataGridColumnHeadersPresenter x:Name="PART_ColumnHeadersPresenter"
Grid.Column="1">
<Custom:DataGridColumnHeadersPresenter.Visibility>
<Binding Path="HeadersVisibility"
RelativeSource="{RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type Controls:DataGrid}}">
<Binding.ConverterParameter>
<Controls:DataGridHeadersVisibility>Column</Controls:DataGridHeadersVisibility>
</Binding.ConverterParameter>
</Binding>
</Custom:DataGridColumnHeadersPresenter.Visibility>
</Custom:DataGridColumnHeadersPresenter>
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter"
Grid.ColumnSpan="2"
Grid.Row="1"
Content="{TemplateBinding Content}"
ContentStringFormat="{TemplateBinding ContentStringFormat}"
ContentTemplate="{TemplateBinding ContentTemplate}"
CanContentScroll="{TemplateBinding CanContentScroll}"
CanHorizontallyScroll="False"
CanVerticallyScroll="False" />
<ScrollBar x:Name="PART_VerticalScrollBar"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
Grid.Column="2"
Grid.Row="0"
Grid.RowSpan="2"
Maximum="{TemplateBinding ScrollableHeight}"
Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"
Orientation="Vertical"
ViewportSize="{TemplateBinding ViewportHeight}" />
<Grid Grid.Column="1"
Grid.ColumnSpan="2"
Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding NonFrozenColumnsViewportHorizontalOffset, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type Controls:DataGrid}}}" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ScrollBar x:Name="PART_HorizontalScrollBar"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
Grid.Column="1"
Maximum="{TemplateBinding ScrollableWidth}"
Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"
Orientation="Horizontal"
ViewportSize="{TemplateBinding ViewportWidth}" />
</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>
hope this helps
回答2:
I've always hated that corner. The easiest way around it is to set your DataGrid.Background
color to whatever your header color is, although this will also color the background of an empty DataGrid
if it has a fixed size. You can always avoid that by placing your DataGrid
inside a control that doesn't stretch it's children, like a StackPanel
, or a DockPanel
with LastChildFill="False"
<DockPanel LastChildFill="False">
<DataGrid ItemsSource="{Binding MyCollection}" Background="Silver" />
</DockPanel>
Alternatives include overwriting styles or templates pieces of the DataGrid or it's ScrollBars. Messy, but possible.
回答3:
Enclose your datagrid in Scrollviewer and set its horizontalScrollBarVisibility to hidden and VerticalScrollBarVisibility to Auto.Hope this will help.
来源:https://stackoverflow.com/questions/8526120/change-the-position-of-the-scrollbar-in-a-wpf-datagrid