How to prevent a ListView from expanding the window dimension?
I put a ListView in the middle row of a View. The view is contained in a window that has SizeToContent set to WidthAndHeight. The ListView is initially empty, but the underlying ViewModel fills this list view in the process.
The middle Grid.Row height is set to * to fill the available size of the window. When the ListView receives new items, it will at some point expand the window size instead of displaying the ScrollViewer in the ListView. How can I prevent this behavior to have SizeToContent set to WidthAndHeight, the Grid.Row height to * but not have the ListView expand the window dimensions?
Here's the code for the window (the Workspace property will contain the ViewModel):
<Window x:Class="Views.ContainerWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="{Binding Title}"
SizeToContent="WidthAndHeight">
<ContentControl Content="{Binding Workspace}"/>
</Window>
The View for the provided ViewModel looks like this:
<UserControl x:Class="开发者_如何转开发Views.SomeView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
MinHeight="450">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0"
TextWrapping="Wrap"
Margin="5"
Text="Some description text"/>
<ListView Grid.Row="1"
ItemsSource="{Binding ItemsList}"
Margin="5">
<ListView.View>
<GridView>
...
</GridView>
</ListView.View>
</ListView>
<Button Grid.Row="2"
HorizontalAlignment="Right"
Command" Value="{Binding CloseCommand}"/>
</Grid>
</UserControl>
Would turning off the window autosizing after it has loaded work for you?
private void Window_Loaded(object sender, RoutedEventArgs e)
{
this.SizeToContent = SizeToContent.Manual;
}
You will have to restrict one of the dynamically sized elements in the hierarchy. I.e. set maximumheight
/maximumwith
or the height
/with
properties of the windown, the grid, or the listboxt to an appropriate value.
As AxelEckenberger wrote more than 10 years ago, to achieve this you will have to set the MaxHeight
of the ListView to be equal to the height of its parent. Unfortunately, he did not explain how to achieve this.
Here is how to make any control fit within its parent:
<ParentControl>
<ChildControl Height="200"
MaxHeight="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type ParentControl}}, Path=ActualHeight,
Mode=OneWay}">
</ChildControl>
</ParentControl>
Notes:
- Binding to
ActualHeight
instead ofHeight
prevents a warning from appearing in the "XAML Binding Failures" view of Visual Studio saying thatNaN
is not a valid value forMaxHeight
. - Strictly speaking,
Mode=OneWay
is unnecessary, sinceMaxHeight
is unlikely to change, but it serves to document the fact that we only expectMaxHeight
to be set fromActualHeight
and we never intend the opposite to happen.
You can actually put your ListView into a Dockpanel, works fine for me:
<Grid x:Name="QueryNinjasGrid" Grid.Row="1">
<DockPanel>
<Button DockPanel.Dock="Top" x:Name="QueryNinjasButton" Content="Query Ninjas" FontSize="20" Margin="20" MaxWidth="150" Click="QueryNinjasButton_Click"/>
<ListView x:Name="NinjaListView" VerticalAlignment="Stretch" MinHeight="150" ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.CanContentScroll="False" >
<ListView.View>
<GridView>
<GridViewColumn Header="Id" Width="20" DisplayMemberBinding="{Binding Id}"/>
<GridViewColumn Header="Name" Width="150" DisplayMemberBinding="{Binding Name}" />
</GridView>
</ListView.View>
</ListView>
</DockPanel>
</Grid>
精彩评论