wpf 如何让 ScrollViewer 在 StackPanel 中工作?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/802821/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 20:19:06  来源:igfitidea点击:

How can I get ScrollViewer to work inside a StackPanel?

wpfxamlscrollviewerstackpanel

提问by Edward Tanguay

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 更改为 Grid 并且它会起作用。

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。我必须对 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>

采纳答案by Kent Boogaart

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. 它旨在朝一个方向无限增长。我建议使用不同的Panel. 为什么你“需要”有一个外部StackPanel

回答by Rob

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>

回答by T.J.Kjaer

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:

效果很好。绑定引用的“页面”确实是不同的、复杂的 UserControl,我只想在其中的一些上只有滚动条。所以我删除了滚动查看器:

 <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 作为我想要它们的用户控件的顶部元素。然而,这并没有奏效。内容刚刚流出页面。起初我不认为这个问题/答案可以帮助我,但我意识到 ItemsControl 的默认 ItemPanel 是 StackPanel。所以我通过指定一个不是 StackPanel 的 ItemsPanel 解决了我的问题:

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

回答by Luis Delgado

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.

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

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

回答by Kylo Ren

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.

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

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

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

Output:

输出:

Scrollbar in Stackpanel

Stackpanel 中的滚动条

回答by Dominic Picard

Here's how I would do it if your stack panel is inside a grid:

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

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

回答by user3522840

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

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

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>