WPF 限制扩展器的大小

Posted

技术标签:

【中文标题】WPF 限制扩展器的大小【英文标题】:WPF Restrict size of an expander 【发布时间】:2011-05-20 15:09:21 【问题描述】:

我在扩展器中有多个树视图,它们的高度可以随内容一起增长。但是当高度大于窗口的大小时,它就会超出窗口。

显而易见的解决方案是设置 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】:

我能想到的一种方法是将 StackPanel 放在 ScrollViewer 中。这样可以确保它永远不会超出窗口的高度。您不会为每个扩展器获得单独的 Scroll(如果它们在同一个 StackPanel 中?),但我不能 100% 确定您在这里追求什么。

<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 上,您将无法使用 MouseWheel 滚动。解决方法是为每个 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 个扩展器,则只有最后一个会在树视图中显示滚动条。但如果事实证明这是不可能的,我会将您的解决方案标记为答案。 @Joshua:看看我是否理解正确。这是否意味着第一个和第二个树视图的高度永远不会超出窗口的高度?否则,如果第二个 TreeView 展开以使第三个 TreeView 被“推”出窗口,会发生什么?所有 TreeView 都在同一个 StackPanel 中吗? 所有树视图都在同一个堆栈面板中。你是对的,第二个树视图也可能在窗口外扩展(使第三个不可见),但在我的应用程序中这不太可能(但仍然可能)。如果第三个树视图根据剩余空间自动调整大小,那对我来说就足够了;)

以上是关于WPF 限制扩展器的大小的主要内容,如果未能解决你的问题,请参考以下文章

WPF:Scrollviewer 不将内容限制为窗口大小

带有WPF的Aero玻璃框架上类似Windows资源管理器的搜索框

带有 WPF 的 Aero 玻璃框架上类似于 Windows 资源管理器的搜索框

Swift 中带有选择器的协议扩展

索引器的扩展方法,它们会好吗? [关闭]

如何单击折叠的 WPF 扩展器后面的内容?