ScrollViewer не прокручивается в WPF - PullRequest
30 голосов
/ 15 июля 2009

Я использую элемент управления scrollviewer вокруг панели стека, который содержит 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>

Ответы [ 5 ]

46 голосов
/ 15 июля 2009

Попробуйте сетку вокруг ScrollViwer вместо StackPanel. Я думаю, StackPanel обеспечит столько высоты, сколько хочет внутреннее содержимое, поэтому здесь Scrollviwer не работает должным образом, так как его высота не ограничена его родительским элементом управления.

Вы можете понять проблему из приведенного ниже примера.

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

Вышеупомянутый код похож на ваш и не дает полос прокрутки. Но посмотрите на приведенный ниже код, в котором я изменил только StackPanel на Grid (любая панель, которая учитывает размер своих дочерних элементов в зависимости от размера панелей, но стека нет)

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

ОБНОВЛЕНИЕ : Но если вам действительно нужно использовать StackPanel, вам может потребоваться установить размер для ScrollViwer, чтобы получить прокрутку содержимого

24 голосов
/ 15 июля 2009

Вы должны зафиксировать высоту просмотра прокрутки, но можете легко привязать к 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>

Или еще лучше, если вы не можете изменить имя 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>

Это проблема «Вы первый», StackPanel запрашивает у ScrollViewer высоту, а ScrollViewer запрашивает у StackPanel максимальную высоту, которой она может быть.

2 голосов
/ 15 июля 2009

ItemsControl должен содержать ScrollViewer, а не наоборот. Все, что ScrollViewer знает о себе, - это ItemsControl в вашем случае - оно не знает о внутренних предметах.

Попробуйте что-то вроде этого:

<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>
0 голосов
/ 27 апреля 2014

У меня была проблема, из-за которой я показывал ItemsControl в сетке, и для того, чтобы увидеть полосы прокрутки, я должен был задать эту * размер ячейки сетки.

Однако это означало, что ItemsControl всегда заполнял ячейку, даже когда было только несколько значений.

Я хотел, чтобы ItemsControl был достаточно большим, чтобы показать, что у него есть, но если в нем было слишком много элементов, то я хотел, чтобы он прокручивался. В порядке слов я хотел, чтобы это работало только на мониторе любого размера.

У меня сработал этот код в событии Loaded:

Size x = new Size(double.PositiveInfinity, double.PositiveInfinity);
myItemscontrol.Measure(x);
0 голосов
/ 19 марта 2012

Свиток должен быть родителем дочернего элемента для изменения размера, поэтому поместите в него элемент управления изменением размера (в данном случае панель стека).

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

...