Growing ScrollView (Height="Auto" MaxHeight="Stretch")
What I want: I would like to have a ScrollView in my Silverlight 4 application which grows in Height together with the content, but does show a scrollbar if it would otherwise grow heigher than its container.
Solutions I found: I found plenty of asked questions where the solution was to strech the Scrollviewer but that is not what I want. The Scrollviewer should always be as small as possible.
My Problem: To make it a bit more difficult on top of the scrollviewer a header is located which is a stackpanel with static height.
Solution Approch 1: I tried it firstly with plain XAML but I cant figure out how it should work.
<Grid Height="Auto" x:Name="myGrid" >
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Background="AliceBlue">
<!-- Dummy Header-->
</StackPanel>
<ScrollViewer Grid.Row="1" Height="Auto">
<Button Width="100" Height="50" Click="Button_Click" />
<!-- onClick the button will switch between height="600" and 开发者_高级运维height="50"
Code:
private void Button_Click(object sender, RoutedEventArgs e)
{
if (sender is Button)
{
Button btn = (Button)sender;
btn.Height = (btn.Height == 50) ? 600 : 50 ;
}
}
-->
</ScrollViewer>
</Grid>
If You click on the button the it becomes higher and the Scrollviewer will be cut becaus it is to tall. Any sugestions?
Solution Approach 2: Then I tried to set the *max*Height of the ScrollViewer with the actualHeight of the containing container, therefore I inseted a StackPanel around the ScrollViewer. This does work in the VS2010 XAML designer but not on code execution. I have no clue why...
<Grid Height="Auto" x:Name="myGrid" >
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Background="AliceBlue">
<!-- Dummy Header-->
</StackPanel>
<StackPanel Grid.Row="1" x:Name="myStackPanel" Height="Auto" VerticalAlignment="Stretch">
<ScrollViewer Height="Auto" MaxHeight="{Binding ElementName=myStackPanel, Path=ActualHeight}">
<Button Width="100" Height="50" Click="Button_Click" />
<!-- onClick the button will switch between height="600" and height="50"
Code:
private void Button_Click(object sender, RoutedEventArgs e)
{
if (sender is Button)
{
Button btn = (Button)sender;
btn.Height = (btn.Height == 50) ? 600 : 50 ;
}
}
-->
</ScrollViewer>
</StackPanel>
</Grid>
Thanks in advance!
The solution is in the appropriate use of VerticalAlignment
. You want the Grid row that contains the scrollview to be the size of the remaining space. You don't want the Scrollviewer to occupy all that space initially but it needs to be limited to that space. The default VerticalAlignment
of Stretch
would have occupy all the available size. Using Top
instead will cause it to only be as high as it needs to be until the Grid limits it size to the available space.
<Grid x:Name="myGrid" >
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Background="AliceBlue">
<!-- Dummy Header-->
</StackPanel>
<ScrollViewer Grid.Row="1" VerticalAlignment="Top" VerticalScrollBarVisibility="Auto">
</ScrollViewer>
</Grid>
However note the VerticalScrollBarVisibility
which you don't include in your own xaml despite indications in your text that it should. Perhaps in fact this is what you are really after all along. With that in place remove the VerticalAlignment
. Depending on the rest of your scenario you might find that actually have the outline border of the full extent of the scrollviewer makes more sense.
精彩评论