结合 WPF Expander 和 GridSplitter 以及 MinHeight

3

如何漂亮地结合使用GridSplitterExpander,同时尊重上下两个区域的MinHeight

例如:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" MinHeight="200" />    <!-- Main -->
        <RowDefinition Height="Auto" />                 <!-- GridSplitter -->
        <RowDefinition Height="Auto" />                 <!-- Expander -->
    </Grid.RowDefinitions>

    <ListBox>
      <ListBoxItem>A</ListBoxItem>
      <ListBoxItem>...</ListBoxItem>
    </ListBox>

    <GridSplitter Grid.Row="1" Height="3" HorizontalAlignment="Stretch" />

    <Expander Grid.Row="2" Header="Expander" IsExpanded="False">
      <ListBox MinHeight="150">
        <ListBoxItem>X</ListBoxItem>
        <ListBoxItem>...</ListBoxItem>
      </ListBox>
    </Expander>  
</Grid>

如果我不使用ExpanderGridSplitter可以正常工作,并且尊重两个行定义的MinHeight属性。
如果我不使用GridSplitter(并将第二个MinHeight属性移动到第二行定义中),Expander可以正常工作。
但是当两者都被使用时,MinHeight属性就不能被尊重,Expander就不能正常工作了。
是否有一个简单的解决方法?

1
我把你的XAML粘贴到了一个测试项目中,它似乎工作正常,分隔器可以让你调整两个控件的大小,但是它们都不会低于它们的最小高度。还有其他影响吗? - Rachel
@Rachel 我稍微修改了XAML示例,以使问题/期望的行为更清晰。当展开器折叠时,我希望第二行“消失”。当展开器打开时,我希望分隔条调整第二行的大小,但不要使其太小。 - Peter
1个回答

2

RowDefinition上设置一个触发器,根据Expander状态更改MinHeight

 <Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" MinHeight="200" />
        <!-- Main -->
        <RowDefinition Height="Auto" />
        <!-- GridSplitter -->
        <RowDefinition Height="Auto" >
            <RowDefinition.Style>
                <Style TargetType="{x:Type RowDefinition}">
                    <Setter Property="MinHeight" Value="150" /> <!-- Default MinHeight -->
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding ElementName=MyExpander, Path=IsExpanded}" Value="False">
                            <Setter Property="MinHeight" Value="24" /> <!-- MinHeight when Collapsed -->
                            <Setter Property="MaxHeight" Value="24" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </RowDefinition.Style>
        </RowDefinition>
        <!-- Expander -->
    </Grid.RowDefinitions>

    <ListBox>
        <ListBoxItem>A</ListBoxItem>
        <ListBoxItem>...</ListBoxItem>
    </ListBox>

    <GridSplitter Grid.Row="1" Height="3" HorizontalAlignment="Stretch" />

    <Expander x:Name="MyExpander" Grid.Row="2" Header="Expander" IsExpanded="False">
        <ListBox>
            <ListBoxItem>X</ListBoxItem>
            <ListBoxItem>...</ListBoxItem>
        </ListBox>
    </Expander>
</Grid>

默认情况下,行的最小高度为150,但当可展开区域关闭时,它的最小和最大高度都将设置为24(默认可展开区域的高度),强制其高度保持在最小值。


很好,但不幸的是,在移动分隔器后折叠展开器仍然无法重置Row2。(并且分隔器仍然可以调整已折叠展开器的行大小。) - Peter
1
@Peter 如果你想在行折叠时强制设置大小,请使用DataTrigger设置MaxHeight属性。在这种情况下,最简单的方法可能是反转你的触发器,并使默认属性设置器成为展开的情况,而触发器则是折叠的情况。如果你需要,我可以更新我的示例。 - Rachel
修复不匹配的 ElementName=parentExpander / x:Name="MyExpander" 后,工作正常。 - Peter
Expander没有展开时,将相同的技术应用于将GridSplitter的可见性设置为Collapsed也能很好地工作。 - Peter
问题:尽管分隔条达到最大高度,但行内的控件仍然无限增长。 - Peter
此外,在样式中添加默认的MaxHeight似乎有助于解决上述问题。 - Peter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接