我想要一个页眉,然后在其下的ScrollViewer
和一个ItemsControl
,然后在该页脚之下。像这样:
<Window x:Class="MainWindow"
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"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid ShowGridLines="True">
<Grid.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="36"/>
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0">Header</TextBlock>
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
<ItemsControl>
<ItemsControl.Items>
<TextBlock>Item 1</TextBlock>
<TextBlock>Item 2</TextBlock>
<TextBlock>Item 3</TextBlock>
<TextBlock>Item 4</TextBlock>
<TextBlock>Item 5</TextBlock>
</ItemsControl.Items>
</ItemsControl>
</ScrollViewer>
<TextBlock Grid.Row="2">Footer</TextBlock>
</Grid>
</Window>
上面几乎是我想要的,除了中间的行是贪婪的;即使窗户很高,它也会占用尽可能多的空间,将页脚推到窗户底部。
如果我将中间行的定义更改为Height="Auto"
,即使该空间不可用,它也会精确地占用它所需的空间量,因此ScrollViewer
永远不会显示滚动条,如果窗口不够高,页脚将从窗口底部迷失。
我如何做到这一点,如果窗口足够高,足以容纳所有内容,则页脚位于ItemsControl
的正下方,但是如果窗口不够高,则ScrollViewer
显示滚动条,页脚在窗口的底部?
我不一定非要使用Grid
来执行此操作,但是我没有找到其他Panel
来满足我的要求。例如,DockPanel
的标头设置为DockPanel.Dock="Top"
,页脚设置为DockPanel.Dock="Bottom"
,而填充其余部分的ItemsControl
的行为完全相同。
我尝试过的其他一些东西:
VerticalAlignment="Stretch"
上设置TextBlock
:不变。 Height="*"
:仍然不是我想要的;页脚和ItemsControl
的高度相同,因此页脚大部分时间会占用太多空间,或者如果您将窗口做得非常短,则会从窗口底部移出。答案 0 :(得分:1)
也许有一种更优雅的方法,但是至少在以下情况下,以下内容对我有用。这是关于计算ItemsControl中所有项目的实际高度,并根据需要调整Grid的行高。
<Grid ShowGridLines="True" Loaded="Grid_Loaded">
<Grid.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="36"/>
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*" Name="middlerow"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0">Header</TextBlock>
<ScrollViewer Name="scv" Grid.Row="1" VerticalScrollBarVisibility="Auto">
<ItemsControl x:Name="items" Height="Auto" VerticalAlignment="Top">
<ItemsControl.Items>
<TextBlock>Item 1</TextBlock>
<TextBlock>Item 2</TextBlock>
<TextBlock>Item 3</TextBlock>
<TextBlock>Item 4</TextBlock>
</ItemsControl.Items>
</ItemsControl>
</ScrollViewer>
<TextBlock Grid.Row="2">Footer</TextBlock>
</Grid>
在后面的代码中:
private void Grid_Loaded(object sender, RoutedEventArgs e)
{
double height = 0;
foreach (var item in items.Items)
{
height += (item as TextBlock).ActualHeight;
}
if (height < scv.ActualHeight)
{
middlerow.MaxHeight = height;
}
}
答案 1 :(得分:0)
感谢mami's answer的实现方法概念,感谢Markus's answer的约束行的MaxHeight
的想法。
XAML:
<Window x:Class="MainWindow"
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"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid ShowGridLines="True">
<Grid.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="36"/>
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*" MaxHeight="{Binding ItemsMaxHeight,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window}}"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0">Header</TextBlock>
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
<ItemsControl Name="ic" SizeChanged="Ic_SizeChanged">
<ItemsControl.Items>
<TextBlock>Item 1</TextBlock>
<TextBlock>Item 2</TextBlock>
<TextBlock>Item 3</TextBlock>
<TextBlock>Item 4</TextBlock>
<TextBlock>Item 5</TextBlock>
</ItemsControl.Items>
</ItemsControl>
</ScrollViewer>
<TextBlock Grid.Row="2">Footer</TextBlock>
</Grid>
</Window>
后面的代码:
Imports System.ComponentModel
Class MainWindow
Implements INotifyPropertyChanged
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Public ReadOnly Property ItemsMaxHeight As Double
Get
Dim Height = 0.0
Dim icg = ic.ItemContainerGenerator
For i = 0 To ic.Items.Count - 1
Height += DirectCast(icg.ContainerFromIndex(i), FrameworkElement).ActualHeight
Next
Return Height + 6.0 ' 6.0 to account for the size of borders? Not sure :(
End Get
End Property
Private Sub Ic_SizeChanged(sender As Object, e As SizeChangedEventArgs)
If e.HeightChanged Then
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("ItemsMaxHeight"))
End If
End Sub
End Class
在此示例XAML中,我不需要将MaxHeight增加6,但是在我的实际应用中,如果我不添加任何额外内容,则ScrollViewer
始终显示一个滚动条,该滚动条可以滚动了一点。不确定导致差异的原因。