ScrollViewer in ItemsControl - ScrollBar not shown but working
This is not your average "My ScrollViewer isn't working" question...
Assume a window with a grid. The sizes of column 0 and row 1 are set toAuto
, column 1 and row 0 are set to *
. (important)
In cell [0, 0] there is an ItemsControl
with a Template with a StackPanel
inside a ScrollViewer
inside a Grid
. The reason is simple: Show a scroll bar if not all items in the ItemsControl
can be displayed. The visibility of the vertical scrollbar is set to Auto
(important).
In Cell [1, 1] there is a Button
that displays its width.
If the window is too small too display all items in the ItemsControl
this will lead to the following:
The scroll bar will be there but it is not visible. It is working, because I can scroll using the mouse wheel. The reason seems to be that the grid column in which the ItemsControl
is contained is not automatically extended to make space for the scrollbar.
If I change (nearly) any of the parameters, the scroll bar is displayed as expected and the second column is reduced in size. Can anyone explain this odd behavior?
Additional Info:
The following parameter changes will lead to the scrollbar becoming visible:
- Changing size of column 0 to
*
- Changing size of column 1 to
Auto
- Changing size of row 1 to
*
- Removing the
Button
. - Moving the
Button
to [0, 1] or [1, 0] - Manually setting the width of the
ItemsControl
. - Setting the
VerticalScrollBarVisibility
of theScrollViewer
in theItemsControl
toVisible
.
However, changing the button in [1, 1] to something else, e.g. another ItemsControl
doesn't change the strange behavior, so it has nothing to with the button. Furthermore, changing the width of the Button
to something that is smaller than the second column, also doesn't remove that behavior.
Complete sample code for reproduction:
<Window x:Class="WpfApplication4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="343" Width="253">
<Grid>
<Grid.ColumnDefinitions>
<C开发者_StackOverflow中文版olumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ItemsControl>
<ItemsControl.Template>
<ControlTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<StackPanel IsItemsHost="True" />
</ScrollViewer>
</Grid>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.Items>
<Button Content="Column1" Height="500" />
</ItemsControl.Items>
</ItemsControl>
<Button Content="{Binding ActualWidth, RelativeSource={RelativeSource Self}}"
Grid.Column="1" Grid.Row="1" />
</Grid>
</Window>
Looks like it might be a known bug in WPF. This question deals with a ListBox's ScrollViewer, but I think the principal is the same.
As an alternative, you could add something behind the ScrollViewer that has it's width bound to the ScrollViewer's ActualWidth, which will force the column to draw the correct size
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ScrollViewer x:Name="Test" Grid.Row="0" Grid.Column="0"
VerticalScrollBarVisibility="Auto">
<Button Content="Column1" Height="500" />
</ScrollViewer>
<Grid Grid.Column="0" Grid.Row="0"
Width="{Binding ElementName=Test, Path=ActualWidth}" />
<Button Content="{Binding ActualWidth, RelativeSource={RelativeSource Self}}"
Grid.Column="1" Grid.Row="1" />
</Grid>
精彩评论