Как я могу заставить ScrollViewer работать внутри StackPanel?
-
03-07-2019 - |
Вопрос
В следующем WPF XAML ScrollViewer не работает (он отображает полосу прокрутки, но вы не можете прокручивать, и содержимое уходит из окна вниз).
Я могу изменить внешнюю панель стека на сетку, и это будет работать.
Однако в моем приложении, из которого я воспроизвел следующий код, мне нужно иметь внешнюю StackPanel. Что мне нужно сделать со 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>
Решение
Вы не можете этого сделать, не зафиксировав высоту StackPanel
.Он рассчитан на бесконечный рост в одном направлении.Я бы посоветовал использовать другой Panel
.Почему вам "нужно" иметь внешнюю StackPanel
?
Другие советы
Это тоже некоторое время не давало мне покоя, хитрость в том, чтобы поместить вашу stackpanel в scrollviewer.
Кроме того, вам необходимо убедиться, что вы установили для свойства 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>
Обратите внимание, что иногда у вас может быть StackPanel, даже не осознавая этого.В моем случае у меня был такой код
<ScrollViewer>
<ItemsControl ItemsSource="{Binding Pages}"/>
</ScrollViewer>
что сработало отлично."Страницы", на которые ссылается привязка, были действительно разными, сложными пользовательскими элементами управления, и я хотел, чтобы на некоторых из них были только полосы прокрутки.Поэтому я удалил scrollviewer:
<ItemsControl ItemsSource="{Binding Pages}"/>
И затем я поместил ScrollViewer в качестве верхнего элемента в тех usercontrols, где я их хотел.Однако это не сработало.Контент просто утек со страницы.Сначала я не думал, что этот вопрос / ответ может мне помочь, но я понял, что ItemPanel по умолчанию ItemsControl - это StackPanel.Итак, я решил свою проблему, указав ItemsPanel, которая не была StackPanel:
<ItemsControl ItemsSource="{Binding Pages}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
Действительно, способ, которым я решил эту проблему, состоял в том, чтобы удалить внешнюю панель стека и вместо этого установить 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>
Вот как это работает:
<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>
Привязывая Высоту ScrollViewer к внутренней высоте окна.
Логика изменения размера заключается в том, что нам нужно присвоить любому элементу фиксированную высоту или спроектировать вид для использования высоты рендеринга.
Выходной сигнал:
Перемещение Grid.Row ="1" из StackPanel в ScrollViewer полностью решило эту проблему для меня.
У меня был длинный список из примерно 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>
Вот как я бы это сделал, если бы ваша панель стека находилась внутри сетки:
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
<StackPanel MaxHeight="{Binding Path=Height,RelativeSource={RelativeSource
AncestorType=Grid}}">
</StackPanel>
</ScrollViewer>