How to prevent a ListView from expanding the window dimension?
Asked Answered
N

4

5

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>
Natant answered 12/9, 2010 at 12:48 Comment(1)
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.Bridgid
O
4

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;
    }
Orleans answered 8/10, 2010 at 10:50 Comment(2)
Thank you. This is in fact the solution I used. You can see that, if you expand the comments above. :)Natant
@Ninfendo: +1 That's wicked, thank you. I wasted an afternoon trying to figure that out.Allerie
P
2

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.

Pryce answered 12/9, 2010 at 12:58 Comment(6)
I'd rather not do that. I'm looking for a way to not let the ListView expand, if items are added.Natant
I was trying to bind the ListView height or maximum height to the current height of the middle Grid.Row, but that didn't help.Natant
Well you will need to restrict something. If the listbox can grow then you will not see the scroll panel. But the unresticted growth of the lisbox leads to an unrestricted growth of the window. Typlical catch 22. So, IMHO, using a maximum size for the window or lisbox will get you there where you want - make the window as small as possible, but if it gets too big, a scroll bar is shown on the listbox.Pryce
You're probably right, but I'm still looking for that way to prevent the ListView from growing. Everything else is working as expected and the ListView contains a ScrollViewer, so it shouldn't be impossible to display the scrollbars instead of growing vertically in this scenario. :/Natant
Well if you want avoid the list view from growing vertically, you will have to set either the height (does not get smaller or bigger) or maximumHeight (gets smaller but not bigger) attribute of the list view.Pryce
I found a satisfying solution. I need the SizeToContent property only for the initial window state. So I removed that after the window has been loaded. Thanks for your help.Natant
B
0

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.
Bridgid answered 23/7, 2021 at 11:57 Comment(0)
W
-1

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>
Washedup answered 14/7, 2018 at 21:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.