如何让 ScrollViewer 在 StackPanel 中工作?

Posted

技术标签:

【中文标题】如何让 ScrollViewer 在 StackPanel 中工作?【英文标题】:How can I get ScrollViewer to work inside a StackPanel? 【发布时间】:2009-04-29 15:10:20 【问题描述】:

在以下 WPF XAML 中,ScrollViewer 不起作用(它显示滚动条但您无法滚动,并且内容从窗口移到底部)。

我可以将外部 StackPanel 更改为 Grid,它会起作用。

但是,在我复制以下代码的应用程序中,我需要有一个外部 StackPanel。 我必须对 StackPanel 做什么才能使 ScrollViewer 显示可用的滚动条? 例如VerticalAlignment="Stretch" Height="Auto" 不起作用。

 <StackPanel>
        <ScrollViewer>
            <StackPanel>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
            </StackPanel>
        </ScrollViewer>
 </StackPanel>

【问题讨论】:

【参考方案1】:

这也困扰了我一段时间,诀窍是将您的堆栈面板放在滚动查看器中。

另外,您需要确保将滚动查看器的 CanContentScroll 属性设置为 True,这是一个示例:

  <ScrollViewer Grid.Row="1" Margin="299,12,34,54" Name="ScrollViewer1" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" Height="195" CanContentScroll="True">
        <StackPanel Name="StackPanel1" OverridesDefaultStyle="False"  Height="193" Width="376" VerticalAlignment="Top" HorizontalAlignment="Left"></StackPanel>
  </ScrollViewer>

【讨论】:

CanContentScroll 属性在哪里?见msdn.microsoft.com/en-us/library/… Giddy> 请看这个链接:- msdn.microsoft.com/en-us/library/ms612683.aspx “您需要确保将滚动查看器的 CanContentScroll 属性设置为 True”——我仍然无法相信这不是名为“ScrollViewer”的控件的默认设置。 @AndreaAntonangeli 我不认为'CanContentScroll'意味着你认为它的意思。当每个项目(或内容)完成“真”滚动时,当“假”滚动仍然发生但在像素级别时【参考方案2】:

你不能不固定StackPanel 的高度。它旨在无限期地向一个方向增长。我建议使用不同的Panel。为什么你“需要”有一个外部的StackPanel

【讨论】:

想要堆叠东西并使用 Grid 你必须手动管理所有的行和列,但是 DockPanel 工作得很好,所以我会切换到那个,谢谢。 我同意爱德华的观点。根据我的经验,将我的 DataGrids 包装在 DockPanel 中,然后为每个 DataGrid 设置 DockPanel.Dock="Top" 效果很好。 我应该在 UWP 中使用哪个替代控件?没有 DockPanel。谢谢。 对于 UWP,您可以使用 RelativePanel 该死的堆栈面板,我总是不得不用 UWP 上的网格替换它,他们应该改变它的行为它是唯一可以这样工作的面板【参考方案3】:

请注意,有时您可能会在没有意识到的情况下拥有 StackPanel。就我而言,我有这段代码

<ScrollViewer>
  <ItemsControl ItemsSource="Binding Pages"/>
</ScrollViewer>

效果很好。绑定引用的“页面”确实不同,复杂的用户控件,我希望其中一些只有滚动条。所以我删除了滚动查看器:

 <ItemsControl ItemsSource="Binding Pages"/>

然后我将 ScrollViewer 作为顶部元素放在我想要的那些用户控件上。然而,这并没有奏效。内容刚刚从页面流出。起初我不认为这个问题/答案可以帮助我,但我意识到 ItemsControl 的默认 ItemPanel 是 StackPanel。所以我通过指定一个不是 StackPanel 的 ItemsPanel 解决了我的问题:

<ItemsControl ItemsSource="Binding Pages">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

【讨论】:

【参考方案4】:

确实,我解决这个问题的方法是移除外部堆栈面板,而是将滚动查看器设置在主网格内我想要的位置。

        <Grid Style="StaticResource LayoutRootStyle">
    <Grid.RowDefinitions>
        <RowDefinition Height="160"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>        

    <!-- Vertical scrolling grid used in most view states -->    

        <ScrollViewer Grid.Row="1" HorizontalScrollBarVisibility="Auto">
            <StackPanel Orientation="Horizontal">
                <GridView>
                ...
                </GridView>
            </StackPanel>
        </ScrollViewer>        

【讨论】:

将 ScrollView 放在 Height = "*" 的一行的网格中为我解决了这个问题。【参考方案5】:

这就是它的工作原理:

<Window x:Class="TabControl.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        
    xmlns:local="clr-namespace:TabControl"
    Title="MainWindow"    Height="300"   
    DataContext="Binding RelativeSource=RelativeSource Self"         
    >    
<StackPanel>
    <ScrollViewer Height="Binding RelativeSource=RelativeSource Mode=FindAncestor,AncestorType=x:Type Border,Path=ActualHeight" >
        <StackPanel >
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
        </StackPanel>
    </ScrollViewer>
</StackPanel>

通过将 ScrollViewer 的高度绑定到窗口的内部高度。

调整大小的逻辑是我们需要给任何元素固定高度或设计视图以使用渲染高度。

输出:

【讨论】:

有点接近,但不完全。某些控件是 ScrollViewer 的祖先,但位于 Border 和 ScrollViewer 之间,可能有一个边距(我的有),并且与 ActualHeight 值的绑定不会捕捉到这一点。 @AlanMcBee 是的,有很多可能的情况下它不能完美地工作,但这是我给出的解决方案的控制层次结构的最基本情况。但是考虑到逻辑,在大多数情况下您需要做的就是更改绑定中的祖先类型,它应该会再次完美运行。修复的关键在于层次结构中有一个 UI 元素可以帮助我们依赖高度(不一定是边框),只要您能找到可靠的高度,逻辑就可以保持不变。希望它有意义,否则将您的问题作为问题发布,我会尽力提供帮助。 :) x:Type 未找到。 @Bigeyes你用的是哪个.net版本和VS版本? @KyloRen。 Visual Studio 2010 和 .Net 4.0。【参考方案6】:

如果您的堆栈面板位于网格内,我会这样做:

<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
    <StackPanel MaxHeight="Binding Path=Height,RelativeSource=RelativeSource 
              AncestorType=Grid">
    </StackPanel>
</ScrollViewer>

【讨论】:

【参考方案7】:

将 Grid.Row="1" 从 StackPanel 移动到 ScrollViewer 完全为我解决了这个问题。

我有一长串要在 StackPanel 中显示的大约 40 个项目,但只有前 20 个显示。

    <ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
        <StackPanel x:Name="ContentPanel" Margin="12,0,12,0">
        <TextBlock Text="Binding Line1" Margin="9,-7,0,0" Style="StaticResource PhoneTextTitle1Style"/>
        <TextBlock Text="" Margin="10,-2,10,0" Style="StaticResource PhoneTextNormalStyle" />
        ...
        </StackPanel>
    </ScrollViewer>

【讨论】:

【参考方案8】:
<WrapPanel Orientation="Vertical">
        <ScrollViewer>
            <WrapPanel Orientation="Vertical">
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
            </WrapPanel>
        </ScrollViewer>
    </WrapPanel>

【讨论】:

正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于如何让 ScrollViewer 在 StackPanel 中工作?的主要内容,如果未能解决你的问题,请参考以下文章

无法让 WPF ScrollViewer 工作

python imapsave - 来自http://stackp.online.fr/?p=25

使用Canvas使ScrollViewer在代码中顺畅滚动

WPF ContentControl 宽度会增加,但在包裹在 ScrollViewer 中时不会缩小

如何防止 ScrollViewer 在更新时触发 ViewChanged 事件?

如何在 ListBox 中禁用 ScrollViewer?