如何使网格行高仅占用所需的空间,又受其容器中可用空间的限制? [英] How to have Grid row height take only the space it needs, but also be constrained by available space in its container?
问题描述
我想有一个页眉,然后是在ScrollViewer
和ItemsControl
之下,然后是页脚.像这样:
I want to have a header, then below that a ScrollViewer
with an ItemsControl
, then below that a footer. Something like:
<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>
上面几乎是我想要的,除了中间的行是贪婪的;即使窗户很高,它也会占用尽可能多的空间,将页脚推到窗户底部.
The above is almost what I want, except the middle row is greedy; even if the window is very tall, it takes up as much space as it can, pushing the footer to the bottom of the window.
如果我将中间行的定义更改为Height="Auto"
,则即使该空间不可用,它也会恰好占用其所需的空间量,因此ScrollViewer
从不显示滚动条,并且页脚将如果窗户不够高,就会迷失在窗户底部.
If I change the middle row's definition to Height="Auto"
, it takes up exactly the amount of space that it needs, even if that space isn't available, so the ScrollViewer
never shows the scrollbar, and the footer will get lost off the bottom of the window if the window isn't tall enough.
我如何做到这一点,如果窗口足够高,足以容纳所有内容,则页脚位于ItemsControl
的正下方,但是如果窗口不够高,ScrollViewer
将显示滚动条,并且页脚在窗口的底部?
How do I make it so that if the window is tall enough for everything to fit, the footer is immediately below the ItemsControl
, but if the window isn't tall enough, the ScrollViewer
shows a scrollbar and the footer is at the bottom of the window?
我不一定需要使用Grid
来执行此操作,但是我没有找到其他可以执行我想要的操作的Panel
.例如,标头设置为DockPanel.Dock="Top"
的DockPanel
,页脚设置为DockPanel.Dock="Bottom"
的ItemsControl
,填充其余部分的ItemsControl
的行为完全相同.
I don't necessarily need to do this with a Grid
, but I didn't find any other Panel
that would do what I want either. E.g., a DockPanel
with the header set to DockPanel.Dock="Top"
, the footer set to DockPanel.Dock="Bottom"
, and the ItemsControl
filling the rest behaves exactly the same way.
我尝试过的其他一些东西:
Some other stuff I've tried:
- 在页脚
TextBlock
上设置VerticalAlignment="Stretch"
:不变. - 使页脚行
Height="*"
:仍然不是我想要的;页脚和ItemsControl
的高度相同,因此页脚大部分时间占用太多空间,或者如果您将窗口做得非常短,则它会离开窗口底部.
- Setting
VerticalAlignment="Stretch"
on the footerTextBlock
: no change. - Making the footer row
Height="*"
: still not what I want; the footer and theItemsControl
get the same height, so the footer takes up too much space most of the time, or if you make the window extremely short, it goes off the bottom of the window.
推荐答案
感谢妈妈的答案,其中包括为此,请 Markus的答案,以绑定行的MaxHeight
.
Thanks to mami's answer for the concept of how to do this, and Markus's answer for the idea to bind the Row's 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
始终显示可以滚动的滚动条.一点点.不确定导致差异的原因.
In this sample XAML, I don't need to increase the MaxHeight by 6, but in my actual app, if I don't add in a little extra, the ScrollViewer
always shows a scrollbar that can be scrolled a tiny bit. Not sure what causes the discrepancy.
这篇关于如何使网格行高仅占用所需的空间,又受其容器中可用空间的限制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!