网站首页 全球最实用的IT互联网站!

人工智能P2P分享Wind搜索发布信息网站地图标签大全

当前位置:诺佳网 > 软件工程 > 后端开发 > .Net >

WPF开发中实现DataGrid中的数据分页显示,自定义分

时间:2025-07-20 23:51

人气:

作者:admin

标签:

导读:实际开发中,我们可能需要自己写一些自定义的分页设计,所以我们需要学会自己封装一个可以直接套用的分页控件,以下就是一个完整的用例,话不多说,我们直接上代码实现。 1.新...

1.新建一个分页控件View:Pagination2Control

1.1 UI展示如下

<UserControl x:Class="WPFDemoMVVM.Controls.Pagination2Control"
			 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
			 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
			 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
			 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
			 xmlns:local="clr-namespace:WPFDemoMVVM.Controls"
			 xmlns:lang="clr-namespace:WPFDemoMVVM.Resources"
			 xmlns:lex="http://wpflocalizeextension.codeplex.com"
			 lex:ResxLocalizationProvider.DefaultAssembly="WPFDemoMVVM"
			 lex:ResxLocalizationProvider.DefaultDictionary="Lang"
			 lex:LocalizeDictionary.DesignCulture="zh-CN"
			 mc:Ignorable="d" 
			 d:DesignHeight="30" d:DesignWidth="800">
	<UserControl.Resources>
		<Style x:Key="PgBaseButtonStyle" TargetType="Button" >
			<Setter Property="Template">
				<Setter.Value>
					<ControlTemplate TargetType="Button">
						<Border CornerRadius="6"
						 Background="{TemplateBinding Background}"
						 BorderBrush="{TemplateBinding BorderBrush}"
						 BorderThickness="{TemplateBinding BorderThickness}">
							<Grid>
								<ContentPresenter HorizontalAlignment="Center"
						   VerticalAlignment="Center"
						   Content="{TemplateBinding Content}"/>
							</Grid>
						</Border>
					</ControlTemplate>
				</Setter.Value>
			</Setter>
			<Setter Property="Background" Value="#282B3B"/>
			<Setter Property="BorderBrush" Value="#367AFF"/>
			<Setter Property="BorderThickness" Value="1"/>
			<Setter Property="Foreground" Value="White"/>
			<Setter Property="Padding" Value="0"/>
			<Setter Property="Height" Value="30"/>
			<Setter Property="Width" Value="70"/>
			<Setter Property="FontSize" Value="14"/>
			<Setter Property="VerticalAlignment" Value="Center"/>
			<Setter Property="VerticalContentAlignment" Value="Center"/>
			<Setter Property="HorizontalAlignment" Value="Center"/>
			<Setter Property="HorizontalContentAlignment" Value="Center"/>
			<Setter Property="Margin" Value="5 0"/>
			<Style.Triggers>
				<Trigger Property="IsMouseOver" Value="True">
					<Setter Property="Foreground" Value="White"/>
					<Setter Property="BorderThickness" Value="2"/>
					<Setter Property="Cursor" Value="Hand"/>
					<Setter Property="Opacity" Value="1"/>
				</Trigger>
			</Style.Triggers>
		</Style>

		<Style x:Key="PgComBoxStyle" TargetType="ComboBox">
			<Setter Property="Background" Value="#0D0D19"/>
			<Setter Property="FontSize" Value="14"/>
			<Setter Property="Margin" Value="20,0,0,0"/>
			<Setter Property="Height" Value="32"/>
			<Setter Property="Width" Value="80"/>
			<Setter Property="VerticalAlignment" Value="Center"/>
			<Setter Property="HorizontalAlignment" Value="Center"/>
			<Setter Property="BorderBrush" Value="#367AFF"/>
			<Setter Property="BorderThickness" Value="0"/>
			<Setter Property="FontFamily" Value="Arial"/>
		</Style>


		<Style TargetType="TextBlock" x:Key="BaseTextBlockStyle">
			<Setter Property="FontSize" Value="14"/>
			<Setter Property="FontFamily" Value="Arial"/>
			<Setter Property="FontWeight" Value="Normal"/>
			<Setter Property="Opacity" Value="1"/>
			<Setter Property="Background" Value="{x:Null}"/>
			<Setter Property="Foreground" Value="White"/>
			<Setter Property="VerticalAlignment" Value="Center"/>
			<Setter Property="HorizontalAlignment" Value="Center"/>
			<Setter Property="Padding" Value="0"/>
		</Style>

		<Style x:Key="BaseComboBoxStyle" TargetType="ComboBox">
			<Setter Property="Foreground" Value="White"/>
			<Setter Property="Background" Value="#0D0D19"/>
			<Setter Property="BorderThickness" Value="0"/>
			<Setter Property="FontSize" Value="14"/>
			<Setter Property="FontFamily" Value="Arial"/>
			<Setter Property="Width" Value="80"/>
			<Setter Property="Height" Value="32"/>
			<Setter Property="FontSize" Value="14"/>
			<Setter Property="HorizontalAlignment" Value="Right"/>
			<Setter Property="VerticalAlignment" Value="Center"/>
			<Setter Property="Margin" Value="5,0,5,0"/>
			<Setter Property="IsEditable" Value="False"/>
			<Setter Property="ItemTemplate">
				<Setter.Value>
					<DataTemplate>
						<TextBlock Text="{Binding}" Style="{StaticResource BaseTextBlockStyle}" HorizontalAlignment="Center"/>
					</DataTemplate>
				</Setter.Value>
			</Setter>
			<Setter Property="Template">
				<Setter.Value>
					<ControlTemplate TargetType="ComboBox">
						<Grid>
							<ToggleButton
								Name="ToggleButton"
								IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
								ClickMode="Press"
								Background="{TemplateBinding Background}"
								BorderThickness="{TemplateBinding BorderThickness}" Width="{TemplateBinding Width}">
								<Grid>
									<ContentPresenter
									Name="ContentSite"
									IsHitTestVisible="False"
									Content="{TemplateBinding SelectionBoxItem}"
									ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
									VerticalAlignment="Center"
									HorizontalAlignment="Left" Width="60"
									Margin="5,0,0,0"
									RecognizesAccessKey="True"/>
									<Path
									HorizontalAlignment="Right"
									Margin="0,0,6,0"
									VerticalAlignment="Center"
									Data="M 0 0 L 4 4 L 8 0 Z"
									Fill="White"/>
								</Grid>
							</ToggleButton>
							<Popup
							Name="Popup"
							Placement="Bottom"
							IsOpen="{TemplateBinding IsDropDownOpen}"
							AllowsTransparency="True"
							Focusable="False"
							PopupAnimation="Slide">
								<Grid
								Name="DropDown"
								SnapsToDevicePixels="True"
								MinWidth="{TemplateBinding ActualWidth}"
								MaxHeight="200"
								Background="#0D0D19">
									<Border x:Name="DropDownBorder" BorderThickness="0" Background="#0D0D19"/>
									<ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
										<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
									</ScrollViewer>
								</Grid>
							</Popup>
						</Grid>
						<ControlTemplate.Triggers>
							<Trigger Property="HasItems" Value="false">
								<Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/>
							</Trigger>
							<Trigger Property="IsEnabled" Value="false">
								<Setter Property="Foreground" Value="Gray"/>
							</Trigger>
							<Trigger Property="IsMouseOver" Value="True">
								<Setter Property="Background" Value="#1A1A2A"/>
							</Trigger>
						</ControlTemplate.Triggers>
					</ControlTemplate>
				</Setter.Value>
			</Setter>
		</Style>

		<Style TargetType="TextBox" x:Key="BaseTextBoxStyle">
			<Setter Property="Height" Value="32"/>
			<Setter Property="Width" Value="98"/>
			<Setter Property="FontSize" Value="14"/>
			<Setter Property="FontFamily" Value="Arial"/>
			<Setter Property="FontWeight" Value="Normal"/>
			<Setter Property="Opacity" Value="0.8"/>
			<Setter Property="Background" Value="#0C0E1A"/>
			<Setter Property="Foreground" Value="White"/>
			<Setter Property="BorderThickness" Value="0"/>
			<Setter Property="Padding" Value="0"/>
			<Setter Property="VerticalAlignment" Value="Center"/>
			<Setter Property="HorizontalAlignment" Value="Center"/>
			<Setter Property="VerticalContentAlignment" Value="Center"/>
			<Setter Property="HorizontalContentAlignment" Value="Left"/>
			<!-- 设置光标颜色为白色 -->
			<Setter Property="CaretBrush" Value="White"/>
		</Style>

	</UserControl.Resources>

	<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center" >
		<Button Content="«" Command="{Binding PreviousPageCommand}" IsEnabled="{Binding CanGoPrevious}" Style="{DynamicResource PgBaseButtonStyle}" Width="30"/>

		<!-- 页码显示为横向排列 -->
		<ItemsControl ItemsSource="{Binding PageNumbers}">
			<ItemsControl.ItemsPanel>
				<ItemsPanelTemplate>
					<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" />
				</ItemsPanelTemplate>
			</ItemsControl.ItemsPanel>
			<ItemsControl.ItemTemplate>
				<DataTemplate>
					<Button Content="{Binding Display}"
					Margin="2"
					Padding="5,2"
					MinWidth="30"
					IsEnabled="{Binding IsEnabled}"
					Command="{Binding DataContext.GoToPageCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"
					CommandParameter="{Binding PageNumber}" Style="{DynamicResource PgBaseButtonStyle}" Width="30"/>
				</DataTemplate>
			</ItemsControl.ItemTemplate>
		</ItemsControl>

		<Button Content="»" Command="{Binding NextPageCommand}" IsEnabled="{Binding CanGoNext}" Style="{DynamicResource PgBaseButtonStyle}" Width="30"/>

		<TextBlock Text="{lex:Loc PageSize}" VerticalAlignment="Center" Style="{DynamicResource ResourceKey=BaseTextBlockStyle}" FontSize="14" Margin="5 0"/>
		<ComboBox ItemsSource="{Binding PageSizeOptions, Mode=OneWay}" SelectedItem="{Binding ItemsPerPage,  Mode=TwoWay}" Style="{DynamicResource BaseComboBoxStyle}" Margin="5 0"/>

		<!-- 总记录数和页数 -->
		<TextBlock VerticalAlignment="Center" Margin="10,0,0,0" Text="{Binding SummaryText}" Style="{DynamicResource BaseTextBlockStyle}"/>
	</StackPanel>
</UserControl>

1.2 分页控件的ViewModel:Paging2ViewModel

public partial class Paging2ViewModel : ObservableObject
{
	private int _totalItems;
	private int _itemsPerPage = 10;
	private int _currentPage = 1;
	private int _maxVisiblePages = 7;

	[ObservableProperty]
	private ObservableCollection<int> pageSizeOptions;

	//[ObservableProperty]
	//private int pageSize;

	[ObservableProperty]
	private string language;

	public int TotalItems
	{
		get => _totalItems;
		set
		{
			SetProperty(ref _totalItems, value);
			UpdatePagination();
		}
	}

	public int ItemsPerPage
	{
		get => _itemsPerPage;
		set
		{
			SetProperty(ref _itemsPerPage, value);
			UpdatePagination();
		}
	}

	public int CurrentPage
	{
		get => _currentPage;
		set
		{
			SetProperty(ref _currentPage, value);
			UpdatePagination();
		}
	}

	public ObservableCollection<PaginationPageNumber> PageNumbers { get; set; } = new();

	public ICommand NextPageCommand => new RelayCommand(() =>
	{
		if (CurrentPage < TotalPages)
			CurrentPage++;
		PageChanged.Invoke(CurrentPage, ItemsPerPage);
	});

	public ICommand PreviousPageCommand => new RelayCommand(() =>
	{
		if (CurrentPage > 1)
			CurrentPage--;
		PageChanged.Invoke(CurrentPage, ItemsPerPage);
	});

	public ICommand GoToPageCommand => new RelayCommand<int>(page =>
	{
		if (page != CurrentPage)
			CurrentPage = page;
		PageChanged.Invoke(CurrentPage, ItemsPerPage);
	});

	public ICommand CurrentPageChangedCommand { get; set; }

	public int TotalPages => (int)Math.Ceiling((double)TotalItems / ItemsPerPage);

	public bool CanGoNext => CurrentPage < TotalPages;
	public bool CanGoPrevious => CurrentPage > 1;

	public string SummaryText => Language == "zh-CN" ? $"共 {TotalItems} 条 / {TotalPages} 页" : $"total {TotalItems} items / {TotalPages} pages";

	public Paging2ViewModel()
	{
		Language = "zh-CN";
		PageSizeOptions = new ObservableCollection<int> { 10, 20, 50 };
		ItemsPerPage = PageSizeOptions[0];
		CurrentPage = 1;
		UpdatePagination();
	}

	private void UpdatePagination()
	{
		PageNumbers.Clear();
		int totalPages = TotalPages;

		if (totalPages <= _maxVisiblePages)
		{
			for (int i = 1; i <= totalPages; i++)
				AddPageButton(i);
		}
		else
		{
			AddPageButton(1);

			if (CurrentPage > 4)
				AddEllipsis();

			int start = Math.Max(2, CurrentPage - 1);
			int end = Math.Min(totalPages - 1, CurrentPage + 1);

			for (int i = start; i <= end; i++)
				AddPageButton(i);

			if (CurrentPage < totalPages - 3)
				AddEllipsis();

			AddPageButton(totalPages);
		}

		CurrentPageChangedCommand?.Execute(CurrentPage);
		OnPropertyChanged(nameof(SummaryText));
		OnPropertyChanged(nameof(CanGoNext));
		OnPropertyChanged(nameof(CanGoPrevious));
	}

	private void AddPageButton(int number)
	{
		PageNumbers.Add(new PaginationPageNumber
		{
			Display = number.ToString(),
			PageNumber = number,
			IsEnabled = number != CurrentPage
		});
	}

	private void AddEllipsis()
	{
		PageNumbers.Add(new PaginationPageNumber
		{
			Display = "...",
			PageNumber = -1,
			IsEnabled = false
		});
	}

	//partial void OnPageSizeChanged(int value)
	//{
	//    CurrentPage = 1;
	//    OnPropertyChanged(nameof(TotalPages));
	//    OnPropertyChanged(nameof(SummaryText));
	//    //GoToPageCommand(CurrentPage);
	//    UpdatePagination();
	/ 
温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信