如何使ScrollViewer在StackPanel中工作?


74

在以下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>

Answers:


58

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


13
想要堆叠内容并使用Grid,您必须手动管理所有行和列,但是DockPanel可以很好地工作,所以我将切换到该位置,谢谢。
爱德华·坦格

1
我同意爱德华。以我的经验,将我的DataGrids封装在DockPanel中,然后为每个DataGrid设置DockPanel.Dock =“ Top”效果很好。
BitsAndBytes 2015年

2
我应该在UW​​P中使用哪个替代控件?没有DockPanel。谢谢。
Jan Chalupa'3

1
对于UWP,您可以使用RelativePanel
xmashallax '16

2
该死的堆栈面板,我总是必须用UWP上的网格替换它,他们应该改变它的行为,这是唯一以这种方式工作的面板
Alberto Rivelli

58

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

另外,您需要确保将滚动查看器的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/...
吉迪恩

2
吉迪>请访问以下链接: - msdn.microsoft.com/en-us/library/ms612683.aspx
Kushal Waikar

1
“您需要确保将滚动查看器的CanContentScroll属性设置为True” ---我仍然无法相信这不是名为“ ScrollViewer”的控件的默认设置。
安德里亚·安东南盖利

@AndreaAntonangeli我不认为' CanContentScroll '意味着您认为的含义。如果对每个项目(或内容)执行“ true”滚动,则仍然发生“ false”滚动,但是在像素级别上滚动
mcalex19年

8

请注意,有时您可能有一个StackPanel,而没有意识到它。就我而言,我有此代码

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

效果很好。绑定引用的“页面”实际上是不同的,复杂的UserControl,而我希望其中的某些仅具有滚动条。所以我删除了scrollviewer:

 <ItemsControl ItemsSource="{Binding Pages}"/>

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

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

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的Height绑定到Window的Inner Height。

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

输出:

Stackpanel中的滚动条


有点接近,但还不完全一样。某些控件是ScrollViewer的祖先,但位于Border和ScrollViewer之间,可能有一个边距(我的确实有),并且绑定到ActualHeight值将无法捕获该控件。
艾伦·麦比

@AlanMcBee是的,在许多可能的情况下它可能无法完美运行,但这是我给出解决方案的控制层次结构的最基本情况。但是考虑到逻辑,在大多数情况下您需要做的就是更改绑定中的祖先类型,它应该可以再次完美工作。修复的症结在于,层次结构中有一个UI元素可以帮助我们依赖于高度(不一定是边框),只要找到可靠的高度,逻辑就可以保持不变。希望有道理,否则将您的问题发布为问题,我会尽力帮助。:)
Kylo Ren

x:Type未找到。
Bigeyes

@Bigeyes您使用的是哪个.net版本和VS版本?
凯洛·伦(Kylo Ren)2016年

@KyloRen。Visual Studio 2010和.Net 4.0。
Bigeyes

4

确实,我解决该难题的方法是卸下外部堆叠面板,然后将scrollviewer设置在我想要在主网格内的位置。

        <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>        

2

如果您的堆栈面板位于网格内,我将按照以下方法进行操作:

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

1

将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>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.