如何让WPF ListBox内容更新时自动显示滚动条且不改变高度
解决WPF ListBox自动拉伸与滚动条不自动显示问题
问题描述
我制作了一个可拉伸的WPF窗体,拉伸时ListBox能同步展开查看更多行,但一次性向ListBox添加大量项时,其高度会被内容撑大导致超出屏幕,必须手动拉伸窗体后才会显示滚动条。需要实现以下两个行为:
- 手动拉伸窗体时,ListBox同步拉伸
- 添加项时ListBox高度保持固定,自动显示滚动条
已尝试的方案:
- 将ListBox嵌入DockPanel、Canvas、StackPanel等不同容器
- 使用无容器包裹的ListBox
- 调整ScrollViewer相关设置
核心原因
问题根源在于窗体的SizeToContent="WidthAndHeight"属性,该属性会让窗体自动适应所有内容的大小。当ListBox添加大量项时,窗体高度会跟着ListBox一起被撑大,超出屏幕范围,此时ListBox没有被限制高度,自然不会触发滚动条。
解决方案
1. 修改窗体的SizeToContent属性
将窗体的SizeToContent从WidthAndHeight改为Width,这样窗体宽度仍会自适应内容,但高度由初始设置和用户拉伸控制,不会随ListBox内容自动变大。同时给窗体设置MinHeight,保证初始显示的最小高度。
2. 修正ListBox的布局设置
确保ListBox所在的Grid行高度为*(占据剩余空间),并且ListBox的VerticalAlignment="Stretch",让它填满所在行的空间,同时保留MinHeight防止高度过小。另外修正原代码中重复的Grid.Row="1"属性,添加Grid.ColumnSpan="2"让ListBox横跨两列,和上方布局保持一致。
修改后的完整XAML代码
<Window x:Class="B.Revit.BatchUpgrader.Addin.Views.BatchUpgraderWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:B.Revit.BatchUpgrader.Addin.Views" mc:Ignorable="d" Title="Batch Upgrader 1.0" SizeToContent="Width" MinHeight="600" ResizeMode="CanResize" WindowStartupLocation="CenterScreen" ShowInTaskbar="False" Topmost="True"> <Window.Resources> <Style TargetType="Button"> <Setter Property="Height" Value="32"/> <Setter Property="Background" Value="White"/> <Setter Property="BorderThickness" Value="2"/> <Setter Property="BorderBrush" Value="DarkSeaGreen"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Border CornerRadius="5" BorderThickness="1" BorderBrush="#FF9DA57F" Background="#FFF4F7E9"> <ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> </Window.Resources> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <StackPanel Grid.Row="0" Grid.ColumnSpan="2" Margin="4"> <GroupBox Header="File Types" Margin="4"> <StackPanel> <CheckBox Content="Project files *.rvt" Margin="4" IsChecked="{Binding IsProjectUpdate}" /> <CheckBox Content="Family files *.rfa" Margin="4" IsChecked="{Binding IsFamilyUpdate}" /> <CheckBox Content="Template files *.rte, *.rft" Margin="4" IsChecked="{Binding IsTemplateUpdate}" /> </StackPanel> </GroupBox> <GroupBox Header="Saving settings" Margin="4"> <StackPanel> <RadioButton GroupName="SavingSettings" Content="Add a suffix to the file name" Margin="4" IsChecked="{Binding IsAddSuffixSave}" /> <RadioButton GroupName="SavingSettings" Content="Save the updated files in a subfolder" Margin="4" IsChecked="{Binding IsSubFolderSave}" /> <RadioButton GroupName="SavingSettings" Content="Overwrite existing files" Margin="4" IsChecked="{Binding IsOverwriteSave}" /> </StackPanel> </GroupBox> <GroupBox Header="Additional settings" Margin="4"> <StackPanel> <CheckBox Content="Delete backup files after update" Margin="4" IsChecked="{Binding IsDeleteBackup}" IsEnabled="{Binding IsDeleteBackupEnable}"/> <CheckBox Content="Update families in subfolders" Margin="4" IsChecked="{Binding IsIncludeSubFolders}" /> <CheckBox Content="Update by ignoring errors" Margin="4" IsChecked="{Binding IsIgnoringErrors}" /> </StackPanel> </GroupBox> <Button Content="Select folder with Revit files" Height="32" Margin="4" Command="{Binding SelectFolderButton}"> </Button> </StackPanel> <ListBox x:Name="ListFolders" Grid.Row="1" Grid.ColumnSpan="2" MinHeight="80" Margin="8 0" VerticalAlignment="Stretch" ItemsSource="{Binding SelectedDirectories}" SelectedItem="{Binding SelectedFolder}" MouseDoubleClick="ListBox_MouseDoubleClick" KeyDown="ListFolders_KeyDown"> </ListBox> <Button Grid.Row="2" Grid.Column="0" Content="Upgrade" Height="32" MinWidth="160" Margin="8" Command="{Binding RunBatchUpgraderButton}" /> <Button Grid.Row="2" Grid.Column="1" Content="Cancel" Height="32" MinWidth="160" Margin="8" Command="{Binding CancelBatchUpgraderButton}" /> </Grid> </Window>
补充说明
- 修改
SizeToContent="Width"后,窗体高度不会随ListBox内容自动扩展,ListBox被限制在Grid的*行内,当内容超过ListBox高度时会自动显示垂直滚动条。 VerticalAlignment="Stretch"保证ListBox能随窗体拉伸同步扩大,MinHeight="80"避免ListBox被压缩到过小。
内容的提问来源于stack exchange,提问作者Mikita Yankouski
相关产品推荐
相关产品推荐

