¿Cómo modificar la ubicación de la barra de desplazamiento vertical de DataGrid en WPF?

Resuelto: Por favor vea mi respuesta a continuación con el código XAML, una captura de pantalla y una explicación.

Fue un poco difícil titular este, así que déjame explicarte cuál es mi problema. Tengo una cuadrícula de datos que tiene una altura definida, por lo que aparece la barra de desplazamiento. Me gustaría contener la barra de desplazamiento vertical al área que excluye el encabezado. Si bien solo desplaza las filas de datos y no el encabezado, visualmente cubre todo el área de datos a la derecha. El problema con esto es que aparecen dos cuadros (uno arriba y abajo) en el área de la barra de desplazamiento. No estoy seguro de cómo deshacerme de ellos o de cómo contener la barra de desplazamiento en el cuerpo de la cuadrícula de datos.

Lo único que he podido averiguar (y no me gusta su aspecto) es establecer el Fondo de DataGrid en Transparente. Aquí está el resultado:

Como puedes ver, la barra de desplazamiento sobresale molesta. Luego, también está el problema de un espacio entre la barra de desplazamiento horizontal y la última fila si el fondo es transparente:

También hay una solución que elimina el color de fondo de la red de datos para esos dos cuadros, haciéndolos destacar menos:

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

Una solución similar se puede encontrar aquí:Plaza molesta donde se encuentran las barras de desplazamiento

Sin embargo, no se elimina el problema de que la barra de desplazamiento sobresalga de forma incómoda en el lateral.

Algo que probé fue separar el encabezado del cuerpo y colocar el cuerpo en un ScrollViewer vertical, luego colocar el encabezado y el cuerpo en un ScrollViewer horizontal para que ambos puedan desplazarse horizontalmente. Pero, como puede imaginar, esto no funciona bien, porque tiene que desplazarse hacia la derecha para ver la barra de desplazamiento vertical. Estoy seguro de que hay una manera de hacerlo para que se mantenga congelado a la derecha, pero no lo he descubierto. Otro problema es el hecho de que el ancho del encabezado debe coincidir con el mayor ancho posible de cualquier celda en esa columna, o todo estará apagado. Este es el resultado que se muestra cuando se desplaza hacia la derecha:

Soy muy nuevo en el control de plantillas, por lo que no puedo averiguar si esto podría funcionar, porque no puedo encontrar los componentes adecuados:

Si le doy a la barra de desplazamiento vertical un margen negativo a la izquierda (por ejemplo, -6,0,0,0) y un relleno de tamaño similar a la derecha del bloque de celdas (0,0,6,0), la barra de desplazamiento vertical técnicamente debería mover hacia la izquierda. Seguiré experimentando y trataré de resolver esto, a menos que alguien tenga la respuesta para mí (lo que sería increíble).

EDICIÓN # 1:

Bueno, hice algunos progresos y pude establecer el margen de la barra de desplazamiento en (-17,0,0,0). 17 parece ser el ancho de la barra de desplazamiento. Parece que hay una clave específica para su ancho:

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

pero no puedo encontrar una manera de insertar eso como el valor de compensación negativo en el margen dentro de XAML. No sería difícil hacerlo en código detrás ... pero prefiero mantenerlo todo en XAML. De todos modos, aquí está la captura de pantalla del progreso y la parte del código XAML:

Aquí está la parte del código 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>

La parte importante que hace posible el cambio es a mitad del fragmento de código donde establecí Margin = "- 17,0,0,0" para ScrollBar.

Mi problema actual es que no puedo averiguar qué componente compensar a la izquierda en 17 (agregando margen o relleno). He estado jugando con todos ellos y sin suerte hasta ahora. Lo actualizaré tan pronto como lo reciba, a menos que alguien lo descubra antes que yo. Tal como está ahora, la barra de desplazamiento superpondrá cualquier cosa en esa última columna hasta que yo arregle el desplazamiento.

EDITAR # 2:

Por favor, consulte el código XAML actualizado anterior. Lo que hice fue agregar Margin = "0,0,17,0" a ScrollContentPresenter.

Un efecto secundario, con el que puedo vivir completamente, es el hecho de que también compensa el encabezado, pero no lo ves hasta que te desplazas completamente hacia la derecha. Afecta solo el encabezado de la última columna, porque ScrollContentPresenter también lo compensa ... extrañamente, ya que existe un DataGridColumnHeadersPresenter, pero funciona de forma independiente ... así que seguiré trabajando en ello. ScrollContentPresenter, desafortunadamente, no tiene relleno, lo que funcionaría como un encanto. Entonces, ahora tengo que averiguar cómo puedo rellenarla, en lugar de establecer un margen, o averiguar un método diferente.

Un método similar es establecer el margen de la barra de desplazamiento horizontal (que es el que está en la segunda cuadrícula) a 0,0, -17,0. Lo moverá 17 unidades a la derecha. A continuación, establezca el margen de DataGridColumnHeaderPresenter en 0,0, -17,0. Lo moverá 17 unidades a la derecha.

EDICIÓN # 3:

Aquí hay otro método para cualquiera que esté interesado:

Establezca el margen de la barra de desplazamiento vertical en 0, -22,0, -17. -22 es la altura de mis encabezados, así que ajústalo a lo que sea tuyo. Este método estira la barra de desplazamiento para cubrir los dos cuadros blancos.

EDITAR # 4:

Me di cuenta de la solución. Por favor vea mi respuesta para el código XAML, una captura de pantalla y una explicación.

Respuestas a la pregunta(2)

Su respuesta a la pregunta