ListView scrollbar messed up my layout
I have a WPF ListBox that usually shows 4 or 5 items. For my application, this means that I almost never have to display the scrollbar (enough space).
However, if there are more items in the list, I need to show the vertical scrollbar, but as a result, my content has less space and no longer looks pretty against the "background" I created the list behind it.
I like to "reserve" a room in my layout for the scrollbar to appear. Is there a way to do this? (maybe having a scrollbar overlaps the content)
a source to share
Ok, found a solution.
I created a new default style for the ScrollViewer by following this MSDN article . Then I changed the part where the scrollbars are located.
Initial behavior
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" Grid.Column="1">
<ScrollContentPresenter CanContentScroll="True" Content="{TemplateBinding ScrollViewer.Content}" />
</Border>
<ScrollBar Orientation="Vertical" Grid.Row="0" Grid.Column="0" Minimum="0" Maximum="{TemplateBinding ScrollViewer.ScrollableHeight}" Value="{TemplateBinding ScrollViewer.VerticalOffset}" ViewportSize="{TemplateBinding ScrollViewer.ViewportHeight}" Name="PART_VerticalScrollBar" Visibility="{TemplateBinding ScrollViewer.ComputedVerticalScrollBarVisibility}" />
<ScrollBar Orientation="Horizontal" Grid.Row="1" Grid.Column="1" Minimum="0" Maximum="{TemplateBinding ScrollViewer.ScrollableWidth}" Value="{TemplateBinding ScrollViewer.HorizontalOffset}" ViewportSize="{TemplateBinding ScrollViewer.ViewportWidth}" Name="PART_HorizontalScrollBar" Visibility="{TemplateBinding ScrollViewer.ComputedHorizontalScrollBarVisibility}"/>
</Grid>
New behavior
<Grid>
<!-- Presentation below is different from the default: the scrollbar is overlayed on the content. -->
<ScrollContentPresenter CanContentScroll="True" Content="{TemplateBinding ScrollViewer.Content}" />
<ScrollBar Orientation="Vertical" HorizontalAlignment="Right" Minimum="0" Maximum="{TemplateBinding ScrollViewer.ScrollableHeight}" Value="{TemplateBinding ScrollViewer.VerticalOffset}" ViewportSize="{TemplateBinding ScrollViewer.ViewportHeight}" Name="PART_VerticalScrollBar" Visibility="{TemplateBinding ScrollViewer.ComputedVerticalScrollBarVisibility}" />
<ScrollBar Orientation="Horizontal" VerticalAlignment="Bottom" Minimum="0" Maximum="{TemplateBinding ScrollViewer.ScrollableWidth}" Value="{TemplateBinding ScrollViewer.HorizontalOffset}" ViewportSize="{TemplateBinding ScrollViewer.ViewportWidth}" Name="PART_HorizontalScrollBar" Visibility="{TemplateBinding ScrollViewer.ComputedHorizontalScrollBarVisibility}"/>
</Grid>
Scroll bars now overlap content so they don't take up extra space when visible. Of course, the content must now reserve space for the content.
a source to share
As you said in your question, you just need to reserve the width for the vertical scrollbar, the following XAML will give you some idea.
<ScrollViewer VerticalScrollBarVisibility="Auto">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/> <!-- reserved for the vertical scrollbar -->
</Grid.ColumnDefinitions>
<Listbox .../>
</Grid>
</ScrollViewer>
a source to share