如何让ScrollViewer在StackPanel中工作?

时间:2022-04-11 09:17:24

In the following WPF XAML the ScrollViewer does not work (it displays a scroll bar but you cannot scroll and the contents go off the window to the bottom).

在下面的WPF XAML中,ScrollViewer不工作(它显示一个滚动条,但您不能滚动,内容从窗口到底部)。

I can change the outer StackPanel to a Grid and it will work.

我可以把外部的StackPanel改成一个网格,它就可以工作了。

However, in my application from which I reproduced the following code, I need to have an outer StackPanel. What do I have to do to the StackPanel to make the ScrollViewer show a usable scrollbar? e.g. VerticalAlignment="Stretch" Height="Auto" don't work.

然而,在我复制以下代码的应用程序中,我需要一个外部堆栈面板。我需要对StackPanel做什么才能使ScrollViewer显示一个可用的滚动条?垂直对齐="拉伸"高度="自动"不起作用。

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

6 个解决方案

#1


49  

You can't without fixing the height of the StackPanel. It's designed to grow indefinitely in one direction. I'd advise using a different Panel. Why do you "need" to have an outer StackPanel?

你不可能不固定StackPanel的高度。它被设计成无限地朝一个方向生长。我建议使用不同的面板。为什么你“需要”有一个外部的堆叠面板?

#2


51  

This was bugging me for a while too, the trick is to put your stackpanel within a scrollviewer.

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

Also, you need to ensure that you set the CanContentScroll property of the scroll viewer to True, here's an example:

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

#3


8  

Notice that sometimes you might have a StackPanel without realizing it. In my case I had this code

请注意,有时您可能有一个StackPanel却没有意识到。在我的例子中,我有这段代码。

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

which worked fine. The "Pages" referenced by the binding was really different, complex UserControls, and I wanted to have only scrollbars on some of them. So I removed the scrollviewer:

它工作得很好。绑定引用的“页面”是完全不同的、复杂的用户控件,我希望其中一些页面上只有滚动条。所以我去掉了scrollviewer

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

And then I put the ScrollViewer as the top element on those of the usercontrols where I wanted them. However, this did not work. The content just flowed off the page. At first i didn't think this question/answer could help me, but the I realized that the default ItemPanel of an ItemsControl is the StackPanel. So I solved my problem by specifying an ItemsPanel that was not the StackPanel:

然后我把ScrollViewer放在usercontrols想要的顶部。然而,这并不奏效。内容刚刚从页面上流出。起初,我不认为这个问题/答案可以帮助我,但是我意识到ItemsControl的默认ItemPanel是StackPanel。所以我通过指定一个不是StackPanel的ItemsPanel来解决我的问题:

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

#4


3  

Indeed, the way I solved that dileman was to remove the outer stack panel and instead set the scrollviewer in the position I wanted inside the main grid.

实际上,我解决这个两难问题的方法是删除外部堆栈面板,而将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>        

#5


3  

This is how it works:

这就是它的工作原理:

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

By binding the ScrollViewer's Height to Window's Inner Height.

通过将滚动查看器的高度绑定到窗口的内部高度。

The logic of re-sizing is we need to give any element fix height or design the view to use render height.

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

Output:

输出:

如何让ScrollViewer在StackPanel中工作?

#6


0  

Moving Grid.Row="1" from StackPanel to ScrollViewer completely solved it for me.

移动网格。从StackPanel到ScrollViewer的Row="1"完全解决了这个问题。

I had a long list of some 40 items to show in a StackPanel, but only the first 20 were showing.

我有一长串的40个项目要展示在一个StackPanel中,但只有前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>

#1


49  

You can't without fixing the height of the StackPanel. It's designed to grow indefinitely in one direction. I'd advise using a different Panel. Why do you "need" to have an outer StackPanel?

你不可能不固定StackPanel的高度。它被设计成无限地朝一个方向生长。我建议使用不同的面板。为什么你“需要”有一个外部的堆叠面板?

#2


51  

This was bugging me for a while too, the trick is to put your stackpanel within a scrollviewer.

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

Also, you need to ensure that you set the CanContentScroll property of the scroll viewer to True, here's an example:

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

#3


8  

Notice that sometimes you might have a StackPanel without realizing it. In my case I had this code

请注意,有时您可能有一个StackPanel却没有意识到。在我的例子中,我有这段代码。

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

which worked fine. The "Pages" referenced by the binding was really different, complex UserControls, and I wanted to have only scrollbars on some of them. So I removed the scrollviewer:

它工作得很好。绑定引用的“页面”是完全不同的、复杂的用户控件,我希望其中一些页面上只有滚动条。所以我去掉了scrollviewer

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

And then I put the ScrollViewer as the top element on those of the usercontrols where I wanted them. However, this did not work. The content just flowed off the page. At first i didn't think this question/answer could help me, but the I realized that the default ItemPanel of an ItemsControl is the StackPanel. So I solved my problem by specifying an ItemsPanel that was not the StackPanel:

然后我把ScrollViewer放在usercontrols想要的顶部。然而,这并不奏效。内容刚刚从页面上流出。起初,我不认为这个问题/答案可以帮助我,但是我意识到ItemsControl的默认ItemPanel是StackPanel。所以我通过指定一个不是StackPanel的ItemsPanel来解决我的问题:

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

#4


3  

Indeed, the way I solved that dileman was to remove the outer stack panel and instead set the scrollviewer in the position I wanted inside the main grid.

实际上,我解决这个两难问题的方法是删除外部堆栈面板,而将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>        

#5


3  

This is how it works:

这就是它的工作原理:

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

By binding the ScrollViewer's Height to Window's Inner Height.

通过将滚动查看器的高度绑定到窗口的内部高度。

The logic of re-sizing is we need to give any element fix height or design the view to use render height.

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

Output:

输出:

如何让ScrollViewer在StackPanel中工作?

#6


0  

Moving Grid.Row="1" from StackPanel to ScrollViewer completely solved it for me.

移动网格。从StackPanel到ScrollViewer的Row="1"完全解决了这个问题。

I had a long list of some 40 items to show in a StackPanel, but only the first 20 were showing.

我有一长串的40个项目要展示在一个StackPanel中,但只有前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>