如何使扩展器控件悬停在下一个元素上?

Kon*_*ten 1 c# wpf layout xaml expander

在我下面举例说明的设置中,直到最近我才注意到当扩展器中列出的元素列表增长时(使其长度超过其旁边面板中按钮的长度),它不会悬停正如直观预期的那样,在数据网格上。相反,它将它向下推,这使得整个 GUI 看起来垂直跳跃。

<StackPanel>
  <StackPanel Orientation="Horizontal">
    <StackPanel>
      <Expander>...</Expander>
    </StackPanel>
    <StackPanel>
      <Button ... /><Button ... /><Button ... />
    </StackPanel>
  </StackPanel>
  <StackPanel Orientation="Horizontal">
    <DataGrid ... />
  </StackPanel>
</StackPanel>
Run Code Online (Sandbox Code Playgroud)

解决此问题的一种方法是将所有内容放在网格中的同一个单元格中,最后添加扩展器。然而,在我看来,这在几个层面上都是不合适的。相反,我更愿意强制扩展器在其他控件上方无接触地扩展。它应该影响布局,但仅影响其折叠状态的大小。扩展不应该影响布局。

我怎么能告诉愚蠢的扩张者不要那么咄咄逼人?

Ste*_*nds 8

作为参考,让我们对StackPanel原始 XAML 中的元素进行编号:

<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>
Run Code Online (Sandbox Code Playgroud)

一个StackPanel面向水平时,将其高度设置为它的最高的孩子,以及面向垂直时,将其高度设置为所有的总和及其子女的高度。

展开Expander控件时,会增加其高度,因此会增加其容器的高度(#3)。这反过来可能会或可能不会增加 #3 的父容器 (#2) 的高度,具体取决于扩展器的高度是否大于包含按钮的堆栈面板 (#4)。

为了达到您似乎想要的效果,您可以使用Grid问题和其他答案中已经讨论过的 a ,也可以使用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>
Run Code Online (Sandbox Code Playgroud)

此处使用的画布允许扩展器控件“逃离”容器的边界。为了让扩展控件“浮动”在它正下方的元素上方(TextBlock在本例中),使用了Panel.ZIndex附加属性。我们还需要将画布的宽度绑定到扩展器的宽度,因为画布不会根据其子项调整自己的大小。

以下是展开器折叠时的外观:

以及展开时的样子:

(请原谅可怕的颜色,它们只是为了让您可以看到控制边界的位置)。