5
votes

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>
4
The stuff about "expanding the window dimension" is a red herring. The question is how to prevent the ListView from expanding vertically as rows are added to it. This will happen regardless of what the parent of the ListView is. The fact that your window happens to have SizeToContent just makes this problem visible to you in particular, but it is irrelevant.Mike Nakis

4 Answers

4
votes

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;
    }
2
votes

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.

0
votes

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 of Height prevents a warning from appearing in the "XAML Binding Failures" view of Visual Studio saying that NaN is not a valid value for MaxHeight.
  • Strictly speaking, Mode=OneWay is unnecessary, since MaxHeight is unlikely to change, but it serves to document the fact that we only expect MaxHeight to be set from ActualHeight and we never intend the opposite to happen.
-1
votes

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>