WPF 限制 Expander 的大小

3
我有多个树形视图在可展开的控件内,随着内容的增加可以增长高度。但当高度大于窗口大小时,会超出窗口。
显而易见的解决方法是设置Treeview的MaxHeight,但我无法轻松确定它,因为可用高度取决于:
- 窗口高度 - 其他展开器(打开/关闭)
我需要改变什么才能使树形视图的高度仍然自动增长,但永远不会大于窗口的高度?
<StackPanel CanVerticallyScroll="True" ClipToBounds="False" Height="Auto" Name="StackPanel2" Width="250" DockPanel.Dock="Left" Orientation="Vertical" VerticalAlignment="Top" CanHorizontallyScroll="False" Margin="5">
    <Border BorderThickness="0" CornerRadius="5" Padding="1" BorderBrush="Red" Margin="0,5" >
        <Expander Header="Expander3" Height="Auto" IsExpanded="False" Width="Auto" Margin="2" BorderThickness="1">
           <Grid  Height="Auto" Width="Auto" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" >

            <TreeView Height="Auto" BorderThickness="1" Margin="0,0,0,0" Padding="7" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" >
           </TreeView>

        </Grid>
    </Expander>
    </Border>
</StackPanel>
1个回答

2

我能想到的一个方法是将StackPanel放在一个ScrollViewer中。这样可以确保它不会超出窗口的高度。如果您的expanders都在同一个StackPanel中,您将不会为每个expander获得单独的滚动条,但我不确定您想要什么。

<ScrollViewer Name="stackPanelScrollViewer"
              Loaded="stackPanelScrollViewer_Loaded"
              VerticalScrollBarVisibility="Auto">
    <StackPanel CanVerticallyScroll="True" ClipToBounds="False" Height="Auto" Name="StackPanel2" Width="250" DockPanel.Dock="Left" Orientation="Vertical" VerticalAlignment="Top" CanHorizontallyScroll="False" Margin="5">
        <Border BorderThickness="0" CornerRadius="5" Padding="1" BorderBrush="Red" Margin="0,5" >
            <Expander Header="Expander3" Height="Auto" IsExpanded="False" Width="Auto" Margin="2" BorderThickness="1">
                <Grid  Height="Auto" Width="Auto" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" >
                    <TreeView Name="treeView1" Height="Auto" BorderThickness="1" Margin="0,0,0,0" Padding="7" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" >
                    </TreeView>
                </Grid>
            </Expander>
        </Border>
    </StackPanel>
</ScrollViewer>

这种方法的缺点是,TreeView 在其 ControlTemplate 中定义了自己的 ScrollViewer,因此如果鼠标位于 TreeView 上方,则无法使用鼠标滚轮进行滚动。解决方法是为每个 TreeView 附加一个 MouseWheel 事件处理程序,并从那里实现滚动。
private void stackPanelScrollViewer_Loaded(object sender, RoutedEventArgs e)
{
    treeView1.AddHandler(MouseWheelEvent, new RoutedEventHandler(StackPanelMouseWheel), true);
    //treeView2.AddHandler(MouseWheelEvent, new RoutedEventHandler(StackPanelMouseWheel), true);
}
private void StackPanelMouseWheel(object sender, RoutedEventArgs e)
{
    MouseWheelEventArgs eargs = (MouseWheelEventArgs)e;
    double x = (double)eargs.Delta;
    double y = stackPanelScrollViewer.VerticalOffset;
    stackPanelScrollViewer.ScrollToVerticalOffset(y - x);
}

谢谢你的回答!我也考虑过这种方法,但我真的需要滚动条在树形视图内部,而不是在堆栈面板或其展开器中。这样,如果我有3个展开器,只有最后一个会在树形视图中显示滚动条。但如果证明这是不可能的,我将把你的解决方案标记为答案。 - Maestro
@Joshua:看看我是否理解正确。这是否意味着第一个和第二个TreeView的高度永远不会超出窗口的高度?否则,如果第二个TreeView扩展,以至于第三个TreeView被“推”到窗口外面,会发生什么?所有的TreeView都在同一个StackPanel中吗? - Fredrik Hedblad
所有的树视图都在同一个堆栈面板中。你说得对,第二个树视图可能也会扩展到窗口外(使第三个不可见),但在我的应用程序中这是不太可能的(但仍然有可能)。如果第三个树视图根据剩余空间自动调整大小,那对我来说就足够了 ;) - Maestro

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