ListBox is contained in a ScrollViewer
I would like the ScrollViewer of the page to be displayed when all开发者_如何学C the information cannot be shown on the screen (i.e. resize the window) However, the ListBox here doesn't get a scroll and it gets sketch till the bottom of the page unless i set it to have a MaxSize. Is there a way to give priority to the ListBox to display its ScrollViewer before the one I have made?
what i have right now http://i.imgur.com/bEJcz.png
what i would like to achieve, but i used a MaxHeight for the ListBox here.
Here's some my markup:
<ScrollViewer HorizontalAlignment="Stretch" VerticalScrollBarVisibility="Auto" Name="scrollViewer1" VerticalAlignment="Stretch" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ComboBox Grid.Row="0" Width="120" HorizontalAlignment="Left"></ComboBox>
<ListBox HorizontalAlignment="Left" Name="listBox" Width="120" Grid.Row="1" <!--MaxHeight="500"--> />
</Grid>
</ScrollViewer>
I know this question is old, but I had exactly the same problem and came up with a bit of a hack as a fix but its better than having the question unsolved.
Much of what I've read states that using things like StackPanel is bad in this case because the panel grows to fit the elements it holds. Normally this works fine because you can stick the StackPanel into a Grid and set the MinHeight and MaxHeight of the column/row and lock the controls in place. As soon as the ScrollView is added this kind of goes to hell. The answer above describes the problem well, but lacks a solution.
I tried many different types of Panels instead of a StackPanel but they all yield the same result. I decided that since my ListBox sits inside of a Grid, I needed to bind the MaxHeight of that grid location to some other value in the control to keep the ListBox from growing. The problem with this is that there is no element that you can bind straight to and get the exact height your looking for.
Enter the hack:
My height was just a tiny bit too big creating a weird always offscreen ListBox (in fact 36 pixels too large, which was the height of the label above the ListBox). So I implemented the IValueConverter:
class HeightToAdjustedHeightConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var height = (double) value - 33d;
return height < 360d ? 360d : height;
//360 being the minimum height allowed for the listbox
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
}
All I did after that was include it as a converter for the binding on MaxHeight (Note you need to name your usercontrol and bind to its x:Name):
<Grid Grid.Column="0"
Grid.Row="1"
VerticalAlignment="Top"
ClipToBounds="True"
MaxHeight="{Binding ElementName=AdHocUserControl, Path=ActualHeight, Converter={StaticResource HeightToAdjustedHeightConverter}}">
The only other alternative I can think of is to extend one of the panels and try to play with its growth behavior. I admit this is a hack, but it will work.
Try this
<ScrollViewer HorizontalAlignment="Stretch" VerticalScrollBarVisibility="Auto" Name="scrollViewer1" VerticalAlignment="Stretch" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ComboBox Grid.Row="0" Width="120" HorizontalAlignment="Left" ></ComboBox>
<ListBox HorizontalAlignment="Left" Name="listBox" Width="120" VerticalAllignment = "Top" Grid.Row="1"/>
</Grid>
</ScrollViewer>
Or you can also try this
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ComboBox Grid.Row="0" Width="120" HorizontalAlignment="Left" ></ComboBox>
<ListBox HorizontalAlignment="Left" Name="listBox" VerticalAlignment= "Top" Width="120" Grid.Row="1" ScrollViewer.VerticalScrollBarVisibility="Auto"/>
</Grid>
You have a logical inconsistency in your definitions.
The requirement as you put it: "I would like the scrollviewer of the page to be displayed when all the information cannot be shown on the screen [without using MaxHeight]" - a question arises: "How do you determine that 'all the information cannot be shown on the screen'?" or "At what point the ListBox
should stop growing and show the scroll bar?".
From a WPF\Silverlight layout management logic, it does exactly what you want - when the sum of height of list box plus the height of the combo box is greater than the ViewportHeight
of the scroll viewer - you get a scroll bar. That is possible only when you allow the ListBox
to grow to it's desired size without scroll bars.
Dont set the MaxHeight on the ListBox
, just use the star '*' notation in your RowDefinitions
to get the relative sizing between your 2 controls correct.
Another solution:
<ScrollViewer HorizontalAlignment="Stretch" VerticalScrollBarVisibility="Auto" Name="scrollViewer1" VerticalAlignment="Stretch" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ComboBox Grid.Row="0" Width="120" HorizontalAlignment="Left"></ComboBox>
<ScrollViewer x:Name="scrollViewer" Grid.Row="1" ScrollViewer.VerticalScrollBarVisibility="Disabled" >
<ListBox HorizontalAlignment="Left" Name="listBox" Width="120" Grid.Row="1" MaxHeight="{Binding ActualHeight, ElementName=scrollViewer}" ScrollViewer.VerticalScrollBarVisibility="Auto"/>
</ScrollViewer>
</Grid>
精彩评论