简体   繁体   English

如何使扩展器控制下一个元素 hover?

[英]How to make an expander control hover over the next element?

In my setup exemplified below, I didn't notice until recently that when the list of elements listed in the expander grows (so that the length of it exceeds the length of the buttons in the panel next to it), it doesn't hover over the data grid, as intuitively expected.在下面举例说明的我的设置中,直到最近我才注意到当扩展器中列出的元素列表增长时(因此它的长度超过了它旁边面板中按钮的长度),它不会 hover正如直观预期的那样,在数据网格上。 Instead, it pushes it down which makes the whole GUI to appear jumpy vertically.相反,它将它向下推,使整个 GUI 在垂直方向上显得跳跃。

<StackPanel>
  <StackPanel Orientation="Horizontal">
    <StackPanel>
      <Expander>...</Expander>
    </StackPanel>
    <StackPanel>
      <Button ... /><Button ... /><Button ... />
    </StackPanel>
  </StackPanel>
  <StackPanel Orientation="Horizontal">
    <DataGrid ... />
  </StackPanel>
</StackPanel>

One way to fix this is to put everything in the same cell in a grid and add the expander last.解决此问题的一种方法是将所有内容放在网格中的同一个单元格中,最后添加扩展器。 However, that seems to me inappropriate on several levels.然而,在我看来,这在几个层面上都是不合适的。 Instead, I'd prefer to force expander to expand touchlessly above the other controls.相反,我更愿意强制扩展器在其他控件上方无接触地扩展。 It should affect the layout but only its size from the folded state. The expansion should not affect the layout at all.它应该会影响布局,但只会影响折叠后的 state 的大小。展开根本不会影响布局。

How can I tell the stupid expander not to be so pushy?我怎么能告诉愚蠢的扩张者不要那么咄咄逼人呢?

For reference, let's number the StackPanel elements from your original XAML: 作为参考,让我们为原始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>

A StackPanel when oriented horizontally will set its height to that of its tallest child, and when oriented vertically will set its height to the sum of all of its children's heights. 水平放置时, StackPanel会将其高度设置为其最高子代的高度,垂直放置时,其高度将设置为其所有子代高度的总和

When you expand the Expander control, you increase its height, and therefore you increase the height of its container (#3). 展开“ Expander控件时,将增加其高度,因此会增加其容器的高度(#3)。 This in turn may or may not increase the height of #3's parent container (#2) depending on whether the expander becomes larger in height than the stack panel containing the buttons (#4). 这反过来可能会或可能不会增加#3的父容器(#2)的高度,这取决于扩展器的高度是否大于包含按钮的堆栈面板(#4)的高度。

To achieve the effect you seem to be after, you can either use a Grid as already discussed in the question and other answer, or you can use a Canvas element like so: 为了达到您似乎想要的效果,您可以使用问题和其他答案中已经讨论过的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>

The canvas as used here allows the expander control to "escape" the boundaries of the container. 这里使用的画布允许扩展器控件“转义”容器的边界。 To get the expander control to "float" above the element directly underneath it (the TextBlock in this example), the Panel.ZIndex attached property is used. 为了使扩展器控件“浮动”在其正下方的元素上方(在此示例中为TextBlock ),使用了Panel.ZIndex附加属性。 We also need to bind the width of the canvas to the width of the expander as the canvas will not size itself based on its children. 我们还需要将画布的宽度绑定到扩展器的宽度,因为画布不会根据其子对象调整大小。

Here's how it looks when the expander is collapsed: 展开器合拢时的外观如下:

And how it looks when it is expanded: 以及扩展后的外观:

(Forgive the horrible colours, they are just so you can see where the control boundaries are). (请原谅可怕的颜色,它们只是为了您可以看到控制边界在哪里)。

This is such a prominent post when you look for answers for this kind of problem, I feel it should be mentioned that a <popup> can work very well in this situation.当你寻找这类问题的答案时,这是一个非常突出的帖子,我觉得应该提到<popup>在这种情况下可以很好地工作。

Place a <popup> inside the content of the expander and you will achieve the same sort of functionality with a much simpler Xaml layout.在扩展器的内容中放置一个<popup> ,您将通过更简单的 Xaml 布局实现相同类型的功能。

Edit: I've explored this option and there's a caveat... Popups are built int to go above OTHER WINDOWS. You'll need to either program the popup to close when the window loses focus or override the template a bit.编辑:我已经探索了这个选项,但有一个警告......弹出窗口内置于 go 高于其他 WINDOWS。您需要对弹出窗口进行编程以在 window 失去焦点时关闭或稍微覆盖模板。 This can also be easily googled.这也可以很容易地用谷歌搜索。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM