Wie ändere ich die Platzierung der vertikalen DataGrid-Bildlaufleiste in WPF?

Gelöst: Bitte sehen Sie meine eigene Antwort unten mit dem XAML-Code, einem Screenshot und einer Erklärung.

Es war ein wenig schwierig, diesen Titel zu vergeben, also lassen Sie mich erklären, was mein Problem ist. Ich habe ein Datagrid mit einer definierten Höhe, daher wird die Bildlaufleiste angezeigt. Ich möchte die vertikale Bildlaufleiste für den Bereich enthalten, der die Kopfzeile ausschließt. Während nur die Datenzeilen und nicht die Kopfzeile gescrollt werden, wird der gesamte Datagrid-Bereich rechts visuell abgedeckt. Das Problem dabei ist, dass zwei Kästchen (eines darüber und eines darunter) im Bereich der Bildlaufleiste angezeigt werden. Ich bin nicht sicher, wie ich sie loswerden soll oder wie ich die Bildlaufleiste auf den Körper des Datagrids setzen soll.

Das Einzige, was ich herausfinden konnte (und was mir nicht gefällt), ist, den Hintergrund des DataGrid auf Transparent zu setzen. Hier ist das Ergebnis:

Wie Sie sehen, ragt die Bildlaufleiste nervig heraus. Dann gibt es auch das Problem einer Lücke zwischen der horizontalen Bildlaufleiste und der letzten Zeile, wenn der Hintergrund transparent ist:

Es gibt auch eine Lösung, die die Hintergrundfarbe des Datagrids für diese beiden Boxen entfernt und sie weniger hervorhebt:

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

Eine ähnliche Lösung finden Sie hier:Ärgerlicher Platz, an dem sich Bildlaufleisten treffen

Das Problem, dass die Bildlaufleiste an der Seite unbeholfen herausragt, wird jedoch nicht behoben.

Etwas, das ich getestet habe, war, die Kopfzeile vom Hauptteil zu trennen und den Hauptteil in einen vertikalen ScrollViewer zu platzieren, und dann die Kopfzeile und den Hauptteil in einen horizontalen ScrollViewer zu platzieren, so dass beide horizontal gescrollt werden können. Aber wie Sie sich vorstellen, funktioniert dies nicht gut, da Sie nach rechts scrollen müssen, um die vertikale Bildlaufleiste zu sehen. Ich bin mir sicher, dass es eine Möglichkeit gibt, es so zu gestalten, dass es rechts eingefroren bleibt, aber ich habe es nicht herausgefunden. Ein weiteres Problem ist die Tatsache, dass die Breite der Überschriften mit der größtmöglichen Breite einer Zelle in dieser Spalte übereinstimmen muss, sonst ist alles deaktiviert. Hier ist das Ergebnis, das angezeigt wird, wenn Sie ganz nach rechts scrollen:

Ich bin sehr neu im Kontrollieren von Vorlagen, daher kann ich nicht herausfinden, ob dies funktionieren könnte, da ich nicht die richtigen Komponenten finde:

Wenn ich der vertikalen Bildlaufleiste einen negativen Rand links (z. B. -6,0,0,0) und einen ähnlich großen Abstand rechts vom Zellenblock (0,0,6,0) gebe, sollte die vertikale Bildlaufleiste technisch gesehen bewege dich nach links. Ich werde weiter experimentieren und versuchen, dies herauszufinden, es sei denn, jemand hat die Antwort für mich (was fantastisch wäre).

EDIT # 1:

Nun, ich habe einige Fortschritte gemacht und konnte den Rand der Bildlaufleiste auf (-17,0,0,0) setzen. 17 scheint die Breite der Bildlaufleiste zu sein. Es scheint einen bestimmten Schlüssel für seine Breite zu geben:

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

Aber ich kann nicht herausfinden, wie ich das als negativen Offsetwert in den Rand innerhalb von XAML einfügen kann. Es wäre nicht schwer, es in Code-Behind zu tun ... aber ich würde lieber alles XAML behalten. Wie auch immer, hier ist der Screenshot des Fortschritts und des XAML-Code-Teils:

Hier ist der XAML-Codeabschnitt:

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

Der wichtige Teil, der die Änderung ermöglicht, befindet sich in der Mitte des Codeausschnitts, in dem ich Margin = "- 17,0,0,0" für ScrollBar festgelegt habe.

Mein aktuelles Problem ist, dass ich nicht herausfinden kann, welche Komponente um 17 nach links versetzt werden muss (entweder durch Hinzufügen eines Randes oder durch Auffüllen). Ich habe mit allen rumgespielt und bisher kein Glück gehabt. Ich werde aktualisieren, sobald ich es bekomme, es sei denn, jemand findet es vor mir heraus. So wie es jetzt ist, überlagert die Bildlaufleiste alles in dieser letzten Spalte, bis ich den Versatz festlege.

EDIT # 2:

Bitte beziehen Sie sich auf den aktualisierten XAML-Code oben. Was ich getan habe, war das Hinzufügen von Margin = "0,0,17,0" zu ScrollContentPresenter.

Ein Nebeneffekt, mit dem ich völlig leben kann, ist die Tatsache, dass der Header ebenfalls versetzt wird, aber Sie sehen das erst, wenn Sie ganz nach rechts scrollen. Es wirkt sich nur auf die Kopfzeile der letzten Spalte aus, da der ScrollContentPresenter dies ebenfalls ausgleicht ... seltsamerweise, da es einen DataGridColumnHeadersPresenter gibt, der jedoch unabhängig funktioniert ... also werde ich weiter daran arbeiten. ScrollContentPresenter hat leider keine Polsterung, was wie ein Zauber wirken würde. Also muss ich jetzt herausfinden, wie ich es auffüllen kann, anstatt einen Rand festzulegen oder eine andere Methode zu finden.

Eine ähnliche Methode besteht darin, den Rand der horizontalen Bildlaufleiste (das ist der im zweiten Raster) auf 0,0, -17,0 festzulegen. Es wird es 17 Einheiten nach rechts bewegen. Setzen Sie dann den Rand von DataGridColumnHeaderPresenter auf 0,0, -17,0. Es wird es 17 Einheiten nach rechts bewegen.

EDIT # 3:

Hier ist eine andere Methode für alle, die interessiert sind:

Setzen Sie den Rand der vertikalen Bildlaufleiste auf 0, -22,0, -17. -22 ist die Höhe meiner Überschriften, passen Sie sie also an Ihre Bedürfnisse an. Diese Methode streckt die Bildlaufleiste, um die beiden weißen Kästchen abzudecken.

EDIT # 4:

Ich fand die Lösung heraus. Bitte sehen Sie meine Antwort für den XAML-Code, einen Screenshot und eine Erklärung.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage