ScrollViewer 是WPF中的一个重要容器控件,它为内容提供滚动功能。与WinForm中的Panel.AutoScroll不同,ScrollViewer提供了更丰富的滚动特性和更好的可定制性。
XML<ScrollViewer Height="200" Width="300">
<!-- 内容区域 -->
<StackPanel>
<TextBlock Text="这是一段很长的内容..." TextWrapping="Wrap"/>
<Button Content="按钮1"/>
<Button Content="按钮2"/>
<!-- 更多内容 -->
</StackPanel>
</ScrollViewer>
XML<ScrollViewer
Height="200"
Width="300"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Visible"
CanContentScroll="True"
PanningMode="Both">
<StackPanel>
<!-- 内容 -->
</StackPanel>
</ScrollViewer>
XML<Window.Resources>
<Style x:Key="CustomScrollViewerStyle" TargetType="ScrollViewer">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ScrollViewer">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- 内容区域 -->
<ScrollContentPresenter Grid.Column="0" Grid.Row="0"/>
<!-- 垂直滚动条 -->
<ScrollBar x:Name="PART_VerticalScrollBar"
Grid.Column="1"
Grid.Row="0"
Value="{TemplateBinding VerticalOffset}"
Maximum="{TemplateBinding ScrollableHeight}"
ViewportSize="{TemplateBinding ViewportHeight}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"/>
<!-- 水平滚动条 -->
<ScrollBar x:Name="PART_HorizontalScrollBar"
Orientation="Horizontal"
Grid.Column="0"
Grid.Row="1"
Value="{TemplateBinding HorizontalOffset}"
Maximum="{TemplateBinding ScrollableWidth}"
ViewportSize="{TemplateBinding ViewportWidth}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<ScrollViewer Style="{StaticResource CustomScrollViewerStyle}">
<!-- 内容 -->
</ScrollViewer>
XML<Window x:Class="AppScrollViewer.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AppScrollViewer"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="Window2" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- ScrollViewer -->
<ScrollViewer x:Name="MyScrollViewer"
Grid.Row="0"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled">
<StackPanel>
<!-- 内容区域 -->
<TextBlock Text="滚动演示标题"
FontSize="24"
FontWeight="Bold"
Margin="10,10,10,20"/>
<!-- 生成多个内容项 -->
<ItemsControl>
<ItemsControl.ItemsSource>
<x:Array Type="{x:Type sys:String}">
<sys:String>第1段内容:这是一段示例文本,用于演示滚动效果。</sys:String>
<sys:String>第2段内容:ScrollViewer是WPF中非常实用的控件,可以方便地管理可滚动内容。</sys:String>
<sys:String>第3段内容:通过设置不同的滚动条可见性,可以精确控制滚动行为。</sys:String>
<sys:String>第4段内容:通过设置不同的滚动条可见性,可以精确控制滚动行为。</sys:String>
<sys:String>第5段内容:通过设置不同的滚动条可见性,可以精确控制滚动行为。</sys:String>
<sys:String>第6段内容:通过设置不同的滚动条可见性,可以精确控制滚动行为。</sys:String>
<sys:String>第7段内容:通过设置不同的滚动条可见性,可以精确控制滚动行为。</sys:String>
<sys:String>第8段内容:通过设置不同的滚动条可见性,可以精确控制滚动行为。</sys:String>
<!-- 重复多次以创建滚动效果 -->
</x:Array>
</ItemsControl.ItemsSource>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"
Margin="10"
TextWrapping="Wrap"
FontSize="16"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</ScrollViewer>
<!-- 控制按钮 -->
<StackPanel Grid.Row="1"
Orientation="Horizontal"
HorizontalAlignment="Center"
Margin="10">
<Button Content="滚动到顶部"
Click="ScrollToTop_Click"
Margin="5,0"/>
<Button Content="滚动到底部"
Click="ScrollToBottom_Click"
Margin="5,0"/>
<Button Content="滚动到指定位置"
Click="ScrollToSpecificOffset_Click"
Margin="5,0"/>
</StackPanel>
</Grid>
</Window>
C#using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace AppScrollViewer
{
/// <summary>
/// Interaction logic for Window2.xaml
/// </summary>
public partial class Window2 : Window
{
private ScrollViewer _scrollViewer;
public Window2()
{
InitializeComponent();
_scrollViewer = MyScrollViewer;
}
private void ScrollToTop_Click(object sender, RoutedEventArgs e)
{
_scrollViewer.ScrollToTop();
}
private void ScrollToBottom_Click(object sender, RoutedEventArgs e)
{
_scrollViewer.ScrollToBottom();
}
private void ScrollToSpecificOffset_Click(object sender, RoutedEventArgs e)
{
// 滚动到垂直100像素位置
_scrollViewer.ScrollToVerticalOffset(100);
}
}
}
XML<ScrollViewer ScrollChanged="ScrollViewer_ScrollChanged"
>
<!-- 内容 -->
</ScrollViewer>
C#private void ScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
// 获取滚动信息
if (e.VerticalChange != 0)
{
double verticalOffset = e.VerticalOffset;
double scrollableHeight = e.ExtentHeight - e.ViewportHeight;
// 计算滚动百分比
double scrollPercentage = (verticalOffset / scrollableHeight) * 100;
Debug.WriteLine($"垂直滚动位置:{scrollPercentage:F2}%");
}
}
XML<ScrollViewer>
<ListBox x:Name="DataListBox"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.VirtualizationMode="Recycling"
ScrollViewer.IsDeferredScrollingEnabled="True">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Border Padding="10" BorderBrush="LightGray" BorderThickness="0,0,0,1">
<StackPanel>
<TextBlock Text="{Binding Name}"
FontWeight="Bold"
FontSize="16"/>
<TextBlock Text="{Binding Description}"
Foreground="Gray"/>
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ScrollViewer>
XML<Window x:Class="AppScrollViewer.Window3"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AppScrollViewer"
mc:Ignorable="d"
Title="Window3" Height="450" Width="800">
<Grid>
<DataGrid x:Name="VirtualDataGrid"
AutoGenerateColumns="False"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.VirtualizationMode="Recycling"
ScrollViewer.IsDeferredScrollingEnabled="True"
GridLinesVisibility="None"
HeadersVisibility="Column">
<DataGrid.Columns>
<DataGridTextColumn Header="名称"
Width="*"
Binding="{Binding Name}"/>
<DataGridTextColumn Header="描述"
Width="2*"
Binding="{Binding Description}"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
C#using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace AppScrollViewer
{
/// <summary>
/// Interaction logic for Window3.xaml
/// </summary>
public partial class Window3 : Window
{
public Window3()
{
InitializeComponent();
LoadVirtualData();
}
private void LoadVirtualData()
{
// 使用更高效的数据源
var items = GenerateLargeDataSet(100000);
VirtualDataGrid.ItemsSource = items;
}
// 快速生成大数据集的方法
private IEnumerable<ItemData> GenerateLargeDataSet(int count)
{
for (int i = 0; i < count; i++)
{
yield return new ItemData
{
Name = $"项目 {i}",
Description = $"详细描述 {i}"
};
}
}
}
// 数据模型
public class ItemData
{
public string Name { get; set; }
public string Description { get; set; }
}
}
XML<ScrollViewer x:Name="ImageScrollViewer"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
PanningMode="Both">
<Image x:Name="DisplayImage"
Stretch="None"
RenderOptions.BitmapScalingMode="HighQuality"/>
</ScrollViewer>
XML<FlowDocumentReader ViewingMode="Scroll">
<FlowDocument>
<Paragraph>
<Run Text="这是一个可滚动的文档内容..."/>
</Paragraph>
<!-- 更多段落 -->
</FlowDocument>
</FlowDocumentReader>
XML<ScrollViewer IsDeferredScrollingEnabled="True">
<!-- 内容 -->
</ScrollViewer>
XML<ScrollViewer>
<ItemsControl VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.VirtualizationMode="Recycling">
<!-- 项目模板 -->
</ItemsControl>
</ScrollViewer>
C#// 禁用动画以提高性能
ScrollViewer.SetCanContentScroll(myScrollViewer, true);
// 设置缓存大小
VirtualizingPanel.SetCacheLength(myItemsControl, new VirtualizationCacheLength(1,1));
ScrollViewer是WPF中非常强大的滚动容器控件,相比WinForm中的滚动面板,它提供了更多的功能和更好的可定制性。掌握ScrollViewer的使用技巧,对于开发高质量的WPF应用程序至关重要。
关键要点:
通过合理使用ScrollViewer,我们可以为用户提供更好的滚动体验,同时保持应用程序的高性能和可维护性。
本文作者:技术老小子
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!