ScrollViewer 概述

用户界面中的内容通常比计算机屏幕的显示区域大。 利用 ScrollViewer 控件可以方便地在 Windows Presentation Foundation (WPF) 应用程序中滚动内容。 本主题介绍 ScrollViewer 元素,并提供若干用法示例。

ScrollViewer 控件

WPF 应用程序中有两个支持滚动的预定义元素:ScrollBarScrollViewerScrollViewer 控件封装了水平和垂直 ScrollBar 元素以及一个内容容器(如 Panel 元素),以便在可滚动的区域中显示其他可见元素。 必须生成自定义对象才能使用 ScrollBar 元素实现内容滚动。 不过,可以单独使用 ScrollViewer 元素,因为它是一个封装了 ScrollBar 功能的复合控件。

ScrollViewer 控件既响应鼠标命令,也响应键盘命令,并定义许多可用于按预设的增量滚动内容的方法。 可以使用 ScrollChanged 事件来检测 ScrollViewer 状态的变化。

ScrollViewer 只能有一个子元素,通常是可承载 Children 元素集合的 Panel 元素。 Content 属性定义 ScrollViewer 的唯一子元素。

物理与逻辑滚动

物理滚动用于按预设的物理增量(通常按以像素为单位声明的值)滚动内容。 逻辑滚动用于滚动到逻辑树中的下一项。 物理滚动是大多数 Panel 元素的默认滚动行为。 WPF 同时支持这两种类型的滚动。

IScrollInfo 接口

IScrollInfo 接口表示 ScrollViewer 或派生控件内的主滚动区域。 该接口定义可由 Panel 元素实现的滚动属性和方法,这些元素需要按逻辑单位(而不是按物理增量)滚动。 通过将 IScrollInfo 的实例转换为派生的 Panel,然后使用其滚动方法,为滚动到子集合中的下一个逻辑单位(而不是按像素增量滚动)提供了有用的方式。 默认情况下,ScrollViewer 控件支持按物理单位滚动。

StackPanelVirtualizingStackPanel 都实现了 IScrollInfo 并且原生支持逻辑滚动。 对于原生支持逻辑滚动的布局控件,仍然可以通过将宿主 Panel 元素放在 ScrollViewer 中并将 CanContentScroll 属性设置为 false 来实现物理滚动。

以下代码示例演示如何将 IScrollInfo 的实例转换为 StackPanel 并使用接口定义的内容滚动方法(LineUpLineDown)。

private void spLineUp(object sender, RoutedEventArgs e)
{
    ((IScrollInfo)sp1).LineUp();
}
private void spLineDown(object sender, RoutedEventArgs e)
{
    ((IScrollInfo)sp1).LineDown();
}
Private Sub spLineUp(ByVal sender As Object, ByVal args As RoutedEventArgs)

    CType(sp1, IScrollInfo).LineUp()
End Sub
Private Sub spLineDown(ByVal sender As Object, ByVal args As RoutedEventArgs)

    CType(sp1, IScrollInfo).LineDown()
End Sub

定义和使用 ScrollViewer 元素

以下示例在包含一些文本和一个矩形的窗口中创建 ScrollViewerScrollBar 元素仅在需要时出现。 重设窗口大小时,由于 ComputedHorizontalScrollBarVisibilityComputedVerticalScrollBarVisibility 属性的值已更新,ScrollBar 元素将在出现后消失。


// Create the application's main window
mainWindow = gcnew System::Windows::Window();
mainWindow->Title = "ScrollViewer Sample";

// Define a ScrollViewer
myScrollViewer = gcnew ScrollViewer();
myScrollViewer->HorizontalScrollBarVisibility = ScrollBarVisibility::Auto;

// Add Layout control
myStackPanel = gcnew StackPanel();
myStackPanel->HorizontalAlignment = HorizontalAlignment::Left;
myStackPanel->VerticalAlignment = VerticalAlignment::Top;

TextBlock^ myTextBlock = gcnew TextBlock();
myTextBlock->TextWrapping = TextWrapping::Wrap;
myTextBlock->Margin = System::Windows::Thickness(0, 0, 0, 20);
myTextBlock->Text = "Scrolling is enabled when it is necessary. Resize the Window, making it larger and smaller.";

Rectangle^ myRectangle = gcnew Rectangle();
myRectangle->Fill = Brushes::Red;
myRectangle->Width = 500;
myRectangle->Height = 500;

// Add child elements to the parent StackPanel
myStackPanel->Children->Add(myTextBlock);
myStackPanel->Children->Add(myRectangle);

// Add the StackPanel as the lone child of the ScrollViewer
myScrollViewer->Content = myStackPanel;

// Add the ScrollViewer as the Content of the parent Window object
mainWindow->Content = myScrollViewer;
mainWindow->Show();


// Create the application's main window
mainWindow = new Window ();
mainWindow.Title = "ScrollViewer Sample";

// Define a ScrollViewer
myScrollViewer = new ScrollViewer();
myScrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;

// Add Layout control
myStackPanel = new StackPanel();
myStackPanel.HorizontalAlignment = HorizontalAlignment.Left;
myStackPanel.VerticalAlignment = VerticalAlignment.Top;

TextBlock myTextBlock = new TextBlock();
myTextBlock.TextWrapping = TextWrapping.Wrap;
myTextBlock.Margin = new Thickness(0, 0, 0, 20);
myTextBlock.Text = "Scrolling is enabled when it is necessary. Resize the Window, making it larger and smaller.";

Rectangle myRectangle = new Rectangle();
myRectangle.Fill = Brushes.Red;
myRectangle.Width = 500;
myRectangle.Height = 500;

// Add child elements to the parent StackPanel
myStackPanel.Children.Add(myTextBlock);
myStackPanel.Children.Add(myRectangle);

// Add the StackPanel as the lone child of the ScrollViewer
myScrollViewer.Content = myStackPanel;

// Add the ScrollViewer as the Content of the parent Window object
mainWindow.Content = myScrollViewer;
mainWindow.Show ();


'Define a ScrollViewer.
Dim myScrollViewer As New ScrollViewer
myScrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto

'Add Layout control.
Dim myStackPanel As New StackPanel
myStackPanel.HorizontalAlignment = System.Windows.HorizontalAlignment.Left
myStackPanel.VerticalAlignment = System.Windows.VerticalAlignment.Top

Dim myTextBlock As New TextBlock
myTextBlock.TextWrapping = TextWrapping.Wrap
myTextBlock.Margin = New Thickness(0, 0, 0, 20)
myTextBlock.Text = "Scrolling is enabled when it is necessary. Resize the Window, making it larger and smaller."

Dim myRectangle As New Rectangle
myRectangle.Fill = Brushes.Red
myRectangle.Width = 500
myRectangle.Height = 500

'Add child elements to the parent StackPanel.
myStackPanel.Children.Add(myTextBlock)
myStackPanel.Children.Add(myRectangle)

'Add the StackPanel as the lone child of the ScrollViewer
myScrollViewer.Content = myStackPanel

'Add the ScrollViewer as the Content of the parent Window object
Me.Content = myScrollViewer
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      WindowTitle="ScrollViewer Sample">
  <ScrollViewer HorizontalScrollBarVisibility="Auto">
    <StackPanel VerticalAlignment="Top" HorizontalAlignment="Left">
      <TextBlock TextWrapping="Wrap" Margin="0,0,0,20">Scrolling is enabled when it is necessary. 
      Resize the window, making it larger and smaller.</TextBlock>
      <Rectangle Fill="Red" Width="500" Height="500"></Rectangle>
    </StackPanel>
  </ScrollViewer>
</Page>

设置 ScrollViewer 的样式

与 Windows Presentation Foundation 中的所有控件一样,可以设置 ScrollViewer 的样式以便更改该控件的默认呈现行为。 有关控件样式设置的其他信息,请参阅样式设置和模板化

对文档进行分页

对于文档内容,一种替代滚动的方法是选择支持分页的文档容器。 FlowDocument 适用于设计为承载于查看控件(例如 FlowDocumentPageViewer)内的文档,该控件支持跨多个页面的内容分页,从而无需进行滚动。 DocumentViewer 提供了一个用于查看 FixedDocument 内容的解决方案,该解决方案使用传统的滚动来显示超出显示区域范围的内容。

有关文档格式和演示选项的其他信息,请参阅 WPF 中的文档

另请参阅