Reputation: 403
I'm try to create a rather complicated window where there are multiple sections showing some lists of data. Now depending on the source, each section can have 1 or more items in the list. If it is possible, it would be best if each list would shrink up to the amount of data, but if the space runs out then show the scroll bar in each ListView.
I thought the grid should contain the ListView. Any ideas what I am missing?
Below is an very simple example that also doesn't do this and I'm not sure why.
<Window x:Class="Test.ListTestWindow1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="ListTestWindow1" Height="400" Width="500">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<StackPanel Orientation="Vertical" HorizontalAlignment="Center">
<Button Content="Some Stuff"/>
<TextBlock Text="More Stuff" />
<Button Content="Place holder"/>
</StackPanel>
</Grid>
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="List Header Group 1" />
<ListView Grid.Row="1">
<ListView.View>
<GridView>
<GridViewColumn Width="120" Header="Date" />
<GridViewColumn Width="120" Header="Day Of Week" DisplayMemberBinding="{Binding DayOfWeek}" />
<GridViewColumn Width="120" Header="Year" DisplayMemberBinding="{Binding Year}" />
</GridView>
</ListView.View>
<sys:DateTime>1/2/3</sys:DateTime>
<sys:DateTime>4/5/6</sys:DateTime>
<sys:DateTime>7/8/9</sys:DateTime>
<sys:DateTime>10/11/12</sys:DateTime>
</ListView>
</Grid>
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="List Header Group 2" />
<ListView Grid.Row="1">
<ListView.View>
<GridView>
<GridViewColumn Width="120" Header="Date" />
<GridViewColumn Width="120" Header="Day Of Week" DisplayMemberBinding="{Binding DayOfWeek}" />
<GridViewColumn Width="120" Header="Year" DisplayMemberBinding="{Binding Year}" />
</GridView>
</ListView.View>
<sys:DateTime>1/2/3</sys:DateTime>
<sys:DateTime>4/5/6</sys:DateTime>
<sys:DateTime>7/8/9</sys:DateTime>
<sys:DateTime>10/11/12</sys:DateTime>
</ListView>
</Grid>
<Grid Grid.Row="2">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="List Header Group 3" />
<ListView Grid.Row="1">
<ListView.View>
<GridView>
<GridViewColumn Width="120" Header="Date" />
<GridViewColumn Width="120" Header="Day Of Week" DisplayMemberBinding="{Binding DayOfWeek}" />
<GridViewColumn Width="120" Header="Year" DisplayMemberBinding="{Binding Year}" />
</GridView>
</ListView.View>
<sys:DateTime>1/2/3</sys:DateTime>
<sys:DateTime>4/5/6</sys:DateTime>
<sys:DateTime>7/8/9</sys:DateTime>
<sys:DateTime>10/11/12</sys:DateTime>
</ListView>
</Grid>
</Grid>
</Grid>
</Window>
Upvotes: 0
Views: 228
Reputation: 102793
If you set a RowDefinition's Height
to Auto
, then it's going to expand to as much as necessary to accommodate whatever's inside the row. So you need to set MaxHeight
on either the RowDefinition
, or its contents (the inner Grids) to restrict the amount it can expand.
You could set the MaxHeight to a static amount if you know it in advance, but more likely you'll want to set it as a percentage of its container (eg, the Window
). To do that, you can bind to the ActualHeight
property of the container. For example:
<Window x:Name="window" xmlns:clr="clr-namespace:System;assembly=mscorlib">
<Grid Name="grid">
<Grid.Resources>
<local:HeightConverter x:Key="HeightConverter" />
<clr:Int32 x:Key="Rows">3</clr:Int32>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" MaxHeight="{Binding ElementName=window,Path=ActualHeight,Converter={StaticResource HeightConverter},ConverterParameter={StaticResource Rows}}">
<!-- contents ... -->
</Grid>
<Grid Grid.Row="1" MaxHeight="{Binding ElementName=window,Path=ActualHeight,Converter={StaticResource HeightConverter},ConverterParameter={StaticResource Rows}}">
<!-- contents ... -->
</Grid>
<Grid Grid.Row="2">
<!-- contents ... -->
</Grid>
</Grid>
</Window>
Here I've used "HeightConverter", which should convert the actual height of the container into the height you want (ie, divide it by three). (You could also just use a fixed amount like MaxHeight=100
if that works for you.) The converter should be something like this:
public class HeightConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
double? containerHeight = (value as double?);
int numberOfRows = (parameter as int?) ?? 1;
var contentHeight = (containerHeight.Value / numberOfRows);
return contentHeight;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Upvotes: 1