如何强制嵌入在扩展器中的 WPF TreeView 重新排列大小?

How to force the WPF TreeView embedded in an Expander to Re-Arrange the size?

我在 Grid.Column 中有 3 个扩展器,它们应该共享可用的 space(高度)。有些扩展器应该得到他们需要的所有 space,有些扩展器在打开时应该 "share" space。所以我创建了一个非常简单的带有 AttachedProperty "ChildShareHeight" 的 StackablePanel。到目前为止一切顺利,我的面板正在为每个扩展器分配正确的 space。不幸的是 Expander.Content 没有按预期做出反应。当 ExpanderContent 块小于 TreeView 时,TreeView 控件的内部 ScrollViewer 不会出现,我找不到如何将 TreeView 大小限制为 Expander.Content 元素大小的方法(以激活 ScrollViewer)或者如何强制更新 Expander.Content 元素的布局。

这两张图说明了我的问题: [1] 够了 space - 没有分享 (https://ibb.co/FBGFxNW) [2] 不够 space - 积极分享 (https://ibb.co/K2s4nB9)。 为了验证布局过程,我在 Expander.Content 元素中找到了一个 "transparent" 面板来跟踪测量和排列功能。每个 Expander 都被正确触发以进行测量和排列,但 Expander.Content 未更新。

我也在寻找其他一些解决方案,例如将 TreeView MaxHeight 属性 绑定到某些外部元素,但我还没有找到任何可行的解决方案。 将整组 Expander 放入 ScrollViewer 对我来说不是一个选择。 有什么解决办法吗?

在我的示例 XAML 下面。

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1*"/>
        <ColumnDefinition Width="3*"/>
        <ColumnDefinition Width="1*"/>
    </Grid.ColumnDefinitions>
    <uic:StackablePanel Grid.Column="1" Margin="10">
        <Expander Header="Expander 1" IsExpanded="False" Margin="5" BorderBrush="Blue" uic:StackablePanel.ChildShareHeight="False">
            <Expander.Content>
                <uic:HeightLimitPanel >
                    <StackPanel Orientation="Vertical" uic:HeightLimitPanel.ExpanderName="Expander 1">
                        <TextBlock Text="Test 10"/>
                       ...
                    </StackPanel>
                </uic:HeightLimitPanel>
            </Expander.Content>
        </Expander>
        <Expander Header="Expander 2" IsExpanded="False" Margin="5" BorderBrush="Red" uic:StackablePanel.ChildShareHeight="True">
            <Expander.Content>
                <uic:HeightLimitPanel >
                    <TreeView uic:HeightLimitPanel.ExpanderName="Expander 2">
                        <TreeViewItem Header="Test 2" IsExpanded="True">
                            <TreeViewItem Header="Text 2.10"/>
                            ...
                            <TreeViewItem Header="Text 2.18"/>
                        </TreeViewItem>
                    </TreeView>
                </uic:HeightLimitPanel>
            </Expander.Content>
        </Expander>
        <Expander Header="Expander 3" IsExpanded="False" Margin="5" BorderBrush="Green" HorizontalAlignment="Stretch" uic:StackablePanel.ChildShareHeight="True" >
            <Expander.Content>
                <uic:HeightLimitPanel>
                    <TreeView uic:HeightLimitPanel.ExpanderName="Expander 3">
                        <TreeViewItem Header="Test 3" IsExpanded="True">
                            <TreeViewItem Header="Text 3.10"/>
                             ...

                            <TreeViewItem Header="Text 3.21"/>
                        </TreeViewItem>
                    </TreeView>
                </uic:HeightLimitPanel>
            </Expander.Content>
        </Expander>
    </uic:StackablePanel>
</Grid>

我使用的是 WPF 库的 MaterialDesign 和自己的扩展控件样式。我在 Style 中发现了一个围绕 ContentPresenter 的 StackPanel。这就是问题所在,为什么 TreeView 不使用嵌入式 ScrollViewer。我在没有 StackPanel 的情况下创建了自己的样式,问题已解决。