ScrollViewer 在 WPF 中不滚动

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1132967/
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:44:24  来源:igfitidea点击:

ScrollViewer not scrolling in WPF

wpfscrollviewer

提问by azamsharp

I am using a scrollviewer control around my stack panel which contains an ItemsControl. When there are many items in the ItemsControl it is suppose to scroll but for some reason it just cuts of the items. Here is the code:

我在包含 ItemsControl 的堆栈面板周围使用滚动查看器控件。当 ItemsControl 中有很多项目时,它应该滚动但由于某种原因它只是剪切了项目。这是代码:

<StackPanel>
    <ScrollViewer CanContentScroll="True" VerticalScrollBarVisibility="Visible">
        <ItemsControl  Name="icEvents" Width="Auto" Height="100"  Background="AliceBlue" 
                       ItemsSource="{Binding Path=EventSources}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="Source:"/>
                        <TextBlock Text="{Binding Path=Source}" />
                        <TextBlock Text="Original Source:"/>
                        <TextBlock Text="{Binding Path=OriginalSource}" />
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </ScrollViewer>
</StackPanel>

回答by Jobi Joy

Try a grid around your ScrollViwerinstead of the StackPanel. I think StackPanelwill provide as much height as the internal content wants, so here the Scrollviwerdoesn't work properly since its height is not get restricted by its parent control.

尝试在您的ScrollViwer而不是StackPanel. 我认为StackPanel将提供尽可能多的内部内容所需的高度,因此这里Scrollviwer无法正常工作,因为其高度不受其父控件的限制。

You can understand the issue from the example below.

你可以从下面的例子中理解这个问题。

<StackPanel>
    <ScrollViewer>
        <ItemsControl >
            <Rectangle Stroke="#FFC3C3C3"  Height="300" Fill="Black" StrokeThickness="4" Width="200"/>
            <Rectangle Stroke="#FFC3C3C3" Width="200" Height="300" Fill="Black" StrokeThickness="4"/>
            <Rectangle Stroke="#FFC3C3C3" Height="300" Fill="Black" StrokeThickness="4" Width="200"/>
            <Rectangle Stroke="#FFC3C3C3" Width="200" Height="300" Fill="Black" StrokeThickness="4"/>
            <Rectangle Stroke="#FFC3C3C3"  Width="200" Height="300" Fill="Black" StrokeThickness="4"/>
        </ItemsControl>
    </ScrollViewer>
</StackPanel>

Above code is similar to yours and it doesn't give you scrollbars. But see the below code in which I changed only the StackPanelto a Grid(Any panel which respects the size of its children based on panels size but stackpanel doesn't)

上面的代码与你的类似,它没有给你滚动条。但是请参阅下面的代码,其中我仅将StackPanela更改为 a Grid(任何基于面板大小尊重其子项大小但 stackpanel 不考虑的面板)

<Grid>
    <ScrollViewer>
        <ItemsControl >
            <Rectangle Stroke="#FFC3C3C3"  Height="300" Fill="Black" StrokeThickness="4" Width="200"/>
            <Rectangle Stroke="#FFC3C3C3" Width="200" Height="300" Fill="Black" StrokeThickness="4"/>
            <Rectangle Stroke="#FFC3C3C3" Height="300" Fill="Black" StrokeThickness="4" Width="200"/>
            <Rectangle Stroke="#FFC3C3C3" Width="200" Height="300" Fill="Black" StrokeThickness="4"/>
            <Rectangle Stroke="#FFC3C3C3"  Width="200" Height="300" Fill="Black" StrokeThickness="4"/>
        </ItemsControl>
    </ScrollViewer>
</Grid>

UPDATE: But if you really need to use StackPanelthen you might need to set the size for your ScrollViwerto get the Content scroll

更新:但是如果您真的需要使用,StackPanel那么您可能需要设置大小ScrollViwer以获取内容滚动

回答by Eduardo Molteni

You must fix the Height of the Scrollviewer, but can easily bind to the StackPanel ActualHeight:
(tested code)

您必须修复 Scrollviewer 的 Height,但可以轻松绑定到 StackPanel ActualHeight:(已
测试代码)

<StackPanel Name="mypanel">
   <ScrollViewer Height="{Binding ElementName=mypanel, Path=ActualHeight}">
       <ItemsControl>
          <Rectangle Stroke="#FFC3C3C3"  Height="300" Fill="Black" Width="200"/>
          <Rectangle Stroke="#FFC3C3C3" Width="200" Height="300" Fill="Black" />
          <Rectangle Stroke="#FFC3C3C3" Height="300" Fill="Black" Width="200"/>
          <Rectangle Stroke="#FFC3C3C3" Width="200" Height="300" Fill="Black" />
          <Rectangle Stroke="#FFC3C3C3"  Width="200" Height="300" Fill="Black" />
      </ItemsControl>
   </ScrollViewer>
</StackPanel>

Or better yet, if you can't change the name of the StackPanel:

或者更好的是,如果您无法更改 StackPanel 的名称:

<StackPanel>
    <ScrollViewer Height="{Binding RelativeSource={RelativeSource FindAncestor, 
                        AncestorType={x:Type StackPanel}}, Path=ActualHeight}">
       <ItemsControl>
          <Rectangle Stroke="#FFC3C3C3"  Height="300" Fill="Black" Width="200"/>
          <Rectangle Stroke="#FFC3C3C3" Width="200" Height="300" Fill="Black" />
          <Rectangle Stroke="#FFC3C3C3" Height="300" Fill="Black" Width="200"/>
          <Rectangle Stroke="#FFC3C3C3" Width="200" Height="300" Fill="Black" />
          <Rectangle Stroke="#FFC3C3C3"  Width="200" Height="300" Fill="Black" />
      </ItemsControl>
   </ScrollViewer>
</StackPanel>

It is a "You first" problem, the StackPanel ask the ScrollViewer for the Height and the ScrollViewer ask the StackPanel for the max Height it can be.

这是一个“你第一”的问题,StackPanel 向 ScrollViewer 询问高度,而 ScrollViewer 向 StackPanel 询问它可以达到的最大高度。

回答by Andy

The ItemsControlshould contain the ScrollViewer, not the other way around. All that the ScrollViewerknows about is the ItemsControlitself in your case - it doesn't know about the inner items.

TheItemsControl应该包含ScrollViewer,而不是相反。在您的情况下,所ScrollViewer知道的只是它ItemsControl本身 - 它不知道内部项目。

Try something like this:

尝试这样的事情:

<ItemsControl Name="icEvents" Width="Auto" Height="100"
    Background="AliceBlue"
    ItemsSource="{Binding Path=EventSources}">
    <ItemsControl.ItemTemplate>
        <DataTemplate> 
            <StackPanel>
                <TextBlock Text="Source:"/>
                <TextBlock Text="{Binding Path=Source}" />
                <TextBlock Text="Original Source:"/>
                <TextBlock Text="{Binding Path=OriginalSource}" />
            </StackPanel>  
        </DataTemplate>
    </ItemsControl.ItemTemplate>
    <ItemsControl.Template>
        <ControlTemplate TargetType="ItemsControl">
            <ScrollViewer VerticalScrollBarVisibility="Auto">
                <ItemsPresenter Margin="5" />
            </ScrollViewer>
        </ControlTemplate>
    </ItemsControl.Template>
</ItemsControl>

回答by MikeT

The Scroll needs to be the parent of the resizing child so, put the resizing control(in this instance the stack panel) inside it.

Scroll 需要是调整大小子项的父项,因此,将调整大小控件(在本例中为堆栈面板)放在其中。

<ScrollViewer>
    <StackPanel>
         <Rectangle Stroke="#FFC3C3C3"  Height="300" Fill="Black" StrokeThickness="4" Width="200"/>
         <Rectangle Stroke="#FFC3C3C3" Width="200" Height="300" Fill="Black" StrokeThickness="4"/>
         <Rectangle Stroke="#FFC3C3C3" Height="300" Fill="Black" StrokeThickness="4" Width="200"/>
         <Rectangle Stroke="#FFC3C3C3" Width="200" Height="300" Fill="Black" StrokeThickness="4"/>
         <Rectangle Stroke="#FFC3C3C3"  Width="200" Height="300" Fill="Black" StrokeThickness="4"/>
    </StackPanel>

回答by Richard Fencel

I had a problem whereby I showed an ItemsControlin a Grid and in order to see the scrollbars, I had to give this Grid cell *-sized height.

我有一个问题,我ItemsControl在网格中显示了一个,为了看到滚动条,我必须给这个网格单元格 * 大小的高度。

However, this meant that the ItemsControlalways filled the cell even when there were only a few values.

但是,这意味着ItemsControl即使只有几个值,也始终填充单元格。

I wanted the ItemsControlto be only big enough to show what it had but if it had too many items then I wanted it to scroll. In order words I wanted this to work only any size monitor.

我希望ItemsControl它足够大以显示它所拥有的东西,但如果它有太多项目,那么我希望它滚动。换句话说,我希望它只适用于任何尺寸的显示器。

This code in the Loaded event worked for me:

Loaded 事件中的这段代码对我有用:

Size x = new Size(double.PositiveInfinity, double.PositiveInfinity);
myItemscontrol.Measure(x);