WPF DataGrid垂直滚动条显示异常:Height与MinHeight设置冲突
WPF DataGrid垂直滚动条异常及横竖屏切换问题
问题现象
- 设置
Height="325"时,VerticalScrollBarVisibility="Visible"生效,滚动条显示,但DataGrid无法自动调整尺寸,部分行无法展示。 - 设置
MinHeight="325"时,DataGrid能正常自适应,但垂直滚动条不显示。 - 切换窗口竖屏(Hochformat)和横屏(Querformat)模式时,上述问题依然存在。
相关代码
XAML代码
<Viewbox Stretch="Uniform" StretchDirection="Both" VerticalAlignment="Top" HorizontalAlignment="Left" Name="ViewBox1"> <Canvas Height="778" Width="1227" > <Canvas.Background> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#FFD6D6D6" Offset="0.596" /> <GradientStop Color="White" Offset="0.163" /> <GradientStop Color="White" Offset="1" /> </LinearGradientBrush> </Canvas.Background> <Button x:Name="ButtonHochformat" Content="Hochformat" Canvas.Left="1056" Canvas.Top="167" Width="75" Click="ButtonHochformat_Click"/> <Button x:Name="ButtonQuerformat" Content="Querformat" Canvas.Left="1056" Canvas.Top="240" Width="75" Click="ButtonQuerformat_Click"/> <DataGrid x:Name="dgFirmaLaender" MinRowHeight="30" ItemsSource="{Binding}" SelectionChanged="DataGrid_SelectionChanged" AlternatingRowBackground="LightGray" AlternationCount="2" FontFamily="Tahoma" FontSize="12" FontWeight="Bold" BorderBrush="DarkGray" BorderThickness="2" VerticalGridLinesBrush="Black" HorizontalGridLinesBrush="Black" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Auto" Width="1227" MinHeight="325" Canvas.Top="453" > <DataGrid.Columns> <DataGridTemplateColumn Header="Flagge" Width="SizeToCells" MinWidth="75" CanUserSort="True" x:Name="SP001" SortMemberPath="ImgFlagge"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <Image x:Name="SP001" Height="30" Width="34" Source="{Binding ImgFlagge}" HorizontalAlignment="Center" VerticalAlignment="Center" Stretch="Fill" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTemplateColumn Header="Aktiv" MinWidth="10" CanUserSort="True" x:Name="SP002" SortMemberPath="AktiveJN" > <DataGridTemplateColumn.CellTemplate> <DataTemplate> <CheckBox x:Name="SP002" IsChecked="{Binding AktiveJN, Mode=TwoWay}" HorizontalContentAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center" VerticalContentAlignment="Center" IsEnabled="False" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTemplateColumn Header="L-KZN" MinWidth="50" CanUserSort="True" x:Name="SP003" SortMemberPath="LandKZN" > <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBox x:Name="SP003" Text="{Binding LandKZN}" HorizontalContentAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center" VerticalContentAlignment="Center" BorderThickness="0" MinWidth="10" FontWeight="Normal" IsReadOnly="True" Background="{Binding Background, RelativeSource={RelativeSource Mode=TemplatedParent}}" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTemplateColumn Header=" Land" CanUserSort="True" x:Name="SP004" MaxWidth="155" SortMemberPath="LandName" > <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBox x:Name="SP004" Text="{Binding LandName}" Width="154" BorderThickness="0" MinWidth="10" FontWeight="Normal" IsReadOnly="True" TextAlignment="Center" Background="{Binding Background, RelativeSource={RelativeSource Mode=TemplatedParent}}" FlowDirection="LeftToRight" HorizontalAlignment="Center" HorizontalContentAlignment="Center" Padding="0,0,5,0" VerticalAlignment="Center" VerticalContentAlignment="Center" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid> </Canvas> </Viewbox>
后台代码(Code Behind)
private void ButtonHochformat_Click(object sender, RoutedEventArgs e) { MyDesktopWindow.WindowState = WindowState.Normal; MyDesktopWindow.Height = 1187; MyDesktopWindow.Width = 778; } private void ButtonQuerformat_Click(object sender, RoutedEventArgs e) { MyDesktopWindow.WindowState = WindowState.Normal; MyDesktopWindow.Height = 778; MyDesktopWindow.Width = 1187; }
解决方案
问题根源在于Canvas容器的特性:Canvas是绝对布局容器,不会限制内部控件的尺寸,也不会响应布局变化。DataGrid放在Canvas里,即使设置了MinHeight,也无法正确计算可用空间,导致滚动条逻辑失效;而设置固定Height时,又会被Viewbox缩放影响,无法自适应窗口变化。
修复步骤:
- 替换Canvas为Grid:Grid是自适应布局容器,能根据父控件尺寸调整内部元素大小,适合响应式场景。
- 调整DataGrid的布局约束:移除Canvas相关的
Canvas.Top属性,改用Grid的行定义来控制位置;同时设置DataGrid的MaxHeight或让它填充Grid的可用空间,确保滚动条在内容超出时触发。 - 优化Viewbox的使用:如果需要整体缩放,确保Grid的尺寸能跟随窗口变化,避免固定宽高导致的适配问题。
修改后的XAML核心部分示例:
<Viewbox Stretch="Uniform" StretchDirection="Both" VerticalAlignment="Top" HorizontalAlignment="Left" Name="ViewBox1"> <!-- 用Grid替换Canvas --> <Grid Width="1227" Height="778"> <Grid.RowDefinitions> <RowDefinition Height="453"/> <!-- 对应原来Canvas.Top的位置 --> <RowDefinition Height="*"/> <!-- 让DataGrid填充剩余空间 --> </Grid.RowDefinitions> <StackPanel Grid.Row="0" HorizontalAlignment="Right" Margin="0,167,100,0"> <Button x:Name="ButtonHochformat" Content="竖屏" Width="75" Click="ButtonHochformat_Click" Margin="0,0,0,20"/> <Button x:Name="ButtonQuerformat" Content="横屏" Width="75" Click="ButtonQuerformat_Click"/> </StackPanel> <DataGrid x:Name="dgFirmaLaender" Grid.Row="1" MinRowHeight="30" ItemsSource="{Binding}" SelectionChanged="DataGrid_SelectionChanged" AlternatingRowBackground="LightGray" AlternationCount="2" FontFamily="Tahoma" FontSize="12" FontWeight="Bold" BorderBrush="DarkGray" BorderThickness="2" VerticalGridLinesBrush="Black" HorizontalGridLinesBrush="Black" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" VerticalScrollBarVisibility="Auto" <!-- 改为Auto,内容超出时自动显示 --> HorizontalScrollBarVisibility="Auto" Width="1227" MinHeight="325" MaxHeight="325" <!-- 保留最小高度的同时限制最大高度,确保滚动条触发 --> > <!-- 列定义保持不变 --> </DataGrid> </Grid> </Viewbox>
关键说明:
- Grid布局:通过行定义将按钮和DataGrid分隔开,确保DataGrid有固定的可用空间,解决Canvas无法约束尺寸的问题。
- VerticalScrollBarVisibility="Auto":比Visible更合理,内容未超出时隐藏滚动条,超出时自动显示。
- MaxHeight+MinHeight组合:既保证DataGrid有最小高度,又限制最大高度,当内容超过MaxHeight时,滚动条自动激活。
- 横竖屏适配:Grid会跟随Viewbox和窗口尺寸变化,自动调整内部元素布局,切换横竖屏时无需额外调整控件位置。
内容的提问来源于stack exchange,提问作者Bernd Riemke
相关产品推荐
相关产品推荐

