Как запретить ListView расширять размер окна?

Я помещаю ListView в среднюю строку View. Представление содержится в окне, для которого SizeToContent задано значение WidthAndHeight. ListView изначально пуст, но базовая модель ViewModel заполняет это представление списка в процессе.

Средняя высота Grid.Row установлена ​​на *, чтобы заполнить доступный размер окна. Когда ListView получает новые элементы, он в какой-то момент расширяет размер окна вместо отображения ScrollViewer в ListView. Как я могу предотвратить такое поведение, чтобы для SizeToContent было установлено значение WidthAndHeight, а для высоты Grid.Row - *, но при этом ListView не расширял размеры окна?

Вот код для окна (свойство Workspace будет содержать 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>

Представление для предоставленной ViewModel выглядит так:

<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>

person Holger Adam    schedule 12.09.2010    source источник
comment
Рассказ о расширении размеров окна - отвлекающий маневр. Вопрос в том, как предотвратить расширение ListView по вертикали при добавлении к нему строк. Это произойдет независимо от того, что является родительским элементом ListView. Тот факт, что в вашем окне есть SizeToContent, только делает эту проблему видимой для вас, но это не имеет значения.   -  person Mike Nakis    schedule 22.07.2021


Ответы (4)


Сработало бы для вас отключение автоматического изменения размера окна после его загрузки?

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        this.SizeToContent = SizeToContent.Manual;
    }
person Fredrik Karlsson Peraldi    schedule 08.10.2010
comment
Спасибо. Фактически, это решение, которое я использовал. В этом можно убедиться, если развернуть комментарии выше. :) - person Holger Adam; 08.10.2010
comment
@Ninfendo: +1 Это ужасно, спасибо. Я потратил день, пытаясь понять это. - person TarkaDaal; 07.02.2013

Вам придется ограничить один из элементов динамического размера в иерархии. Т.е. установите _1 _ / _ 2_ или _3 _ / _ 4_ свойств окна, сетки или списка в соответствующее значение.

person AxelEckenberger    schedule 12.09.2010
comment
Я бы предпочел не делать этого. Я ищу способ не позволять ListView расширяться при добавлении элементов. - person Holger Adam; 12.09.2010
comment
Я пытался привязать высоту ListView или максимальную высоту к текущей высоте среднего Grid.Row, но это не помогло. - person Holger Adam; 12.09.2010
comment
Что ж, вам нужно будет что-то ограничить. Если список может увеличиваться, вы не увидите панель прокрутки. Но неограниченный рост лисбокса приводит к неограниченному разрастанию окна. Типичный улов 22. Итак, IMHO, использование максимального размера для окна или lisbox приведет вас туда, где вы хотите - сделайте окно как можно меньше, но если оно станет слишком большим, в списке отобразится полоса прокрутки. - person AxelEckenberger; 12.09.2010
comment
Вы, наверное, правы, но я все еще ищу способ предотвратить рост ListView. Все остальное работает, как ожидалось, и ListView содержит ScrollViewer, поэтому в этом сценарии не должно быть невозможным отображать полосы прокрутки вместо вертикального роста. : / - person Holger Adam; 13.09.2010
comment
Что ж, если вы хотите, чтобы представление списка не увеличивалось по вертикали, вам нужно будет установить либо атрибут height (не становится меньше или больше), либо атрибут maximumHeight (становится меньше, но не больше) для представления списка. - person AxelEckenberger; 13.09.2010
comment
Я нашел удовлетворительное решение. Мне нужно свойство SizeToContent только для начального состояния окна. Я удалил это после загрузки окна. Спасибо за вашу помощь. - person Holger Adam; 13.09.2010

Как писал AxelEckenberger более 10 лет назад, для этого вам нужно установить MaxHeight ListView равным высоте его родительского элемента. К сожалению, он не объяснил, как этого добиться.

Вот как сделать так, чтобы любой элемент управления соответствовал его родительскому элементу:

<ParentControl>
    <ChildControl Height="200" 
        MaxHeight="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
            AncestorType={x:Type ParentControl}}, Path=ActualHeight,
            Mode=OneWay}">
    </ChildControl>
</ParentControl>

Примечания:

  • Привязка к ActualHeight вместо Height предотвращает появление предупреждения в представлении "Ошибки привязки XAML" в Visual Studio о том, что NaN не является допустимым значением для MaxHeight.
  • Строго говоря, Mode=OneWay не нужен, поскольку MaxHeight вряд ли изменится, но он служит документом того факта, что мы ожидаем, что MaxHeight будет установлен только с ActualHeight, и мы никогда не предполагаем, что произойдет обратное.
person Mike Nakis    schedule 23.07.2021

Фактически вы можете поместить свой ListView в Dockpanel, у меня отлично работает:

<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>
person R3venge    schedule 14.07.2018