Подтвердить что ты не робот

ScrollViewer не прокручивается в WPF

Я использую элемент 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>
4b9b3361

Ответ 1

Попробуйте создать сетку вокруг 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>

UPDATE. Но если вам действительно нужно использовать StackPanel, вам может потребоваться установить размер для ScrollViwer, чтобы получить прокрутку содержимого

Ответ 2

Вы должны исправить высоту Scrollviewer, но можете легко привязываться к 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 для Height и ScrollViewer запрашивает StackPanel для максимальной высоты, которую он может быть.

Ответ 3

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>

Ответ 4

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

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

Ответ 5

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

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

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

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

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