在我下面举例说明的设置中,我直到最近才注意到当扩展器中列出的元素列表增长(因此它的长度超过它旁边面板中按钮的长度)时,它没有如直观预期的那样,将鼠标悬停在数据网格上。相反,它将其向下推,这使整个GUI垂直显示为跳跃。
<StackPanel>
<StackPanel Orientation="Horizontal">
<StackPanel>
<Expander>...</Expander>
</StackPanel>
<StackPanel>
<Button ... /><Button ... /><Button ... />
</StackPanel>
</StackPanel>
<StackPanel Orientation="Horizontal">
<DataGrid ... />
</StackPanel>
</StackPanel>
解决此问题的一种方法是将所有内容放在网格中的同一单元格中,并最后添加扩展器。但是,在我看来,这在几个层面上是不合适的。相反,我更愿意强制扩展器在其他控件的上方 上进行扩展。它应该影响布局,但仅限于折叠状态下的尺寸。扩展不应该影响布局。
我怎么能告诉愚蠢的扩张者不要这么强大?
答案 0 :(得分:4)
作为参考,让我们对原始XAML中的StackPanel
元素进行编号:
<StackPanel #1>
<StackPanel #2 Orientation="Horizontal">
<StackPanel #3>
<Expander>...</Expander>
</StackPanel>
<StackPanel #4>
<Button ... /><Button ... /><Button ... />
</StackPanel>
</StackPanel>
<StackPanel #5 Orientation="Horizontal">
<DataGrid ... />
</StackPanel>
</StackPanel>
水平定向时StackPanel
将其高度设置为最高子项的高度,垂直定向时将其高度设置为所有的总和它的孩子的高度。
展开Expander
控件时,会增加其高度,因此会增加其容器的高度(#3)。这反过来可能会也可能不会增加#3父容器(#2)的高度,具体取决于扩展器的高度是否大于包含按钮的堆栈面板(#4)。
为了达到你想要的效果,你可以使用问题和其他答案中已经讨论过的Grid
,或者你可以使用Canvas
这样的元素:
<Window x:Class="..."
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel>
<StackPanel Orientation="Horizontal" Panel.ZIndex="1">
<Canvas Width="{Binding ActualWidth, ElementName=Expander}">
<Expander x:Name="Expander" Header="Header" Background="Yellow">
<StackPanel Background="Aqua">
<TextBlock Text="Some text" />
<TextBlock Text="Some text" />
<TextBlock Text="Some text" />
<TextBlock Text="Some text" />
<TextBlock Text="Some text" />
<TextBlock Text="Some text" />
</StackPanel>
</Expander>
</Canvas>
<StackPanel>
<Button Content="Button1" />
<Button Content="Button2" />
<Button Content="Button3" />
</StackPanel>
</StackPanel>
<TextBlock Text="Some more text" Background="LimeGreen" />
</StackPanel>
</Window>
此处使用的画布允许扩展器控件“转义”容器的边界。要使扩展器控件“浮动”在其下方的元素上方(本示例中为TextBlock
),将使用Panel.ZIndex
附加属性。我们还需要将画布的宽度绑定到扩展器的宽度,因为画布不会根据其子项自行调整大小。
以下是展开器折叠时的外观:
它在展开时的外观:
(原谅可怕的颜色,它们只是让你可以看到控制边界的位置)。