装饰类:
public class PaginationAdorner : Adorner
{
#region 属性
public static IEnumerable PageSource;
public static DataGrid dataGrid;
public static int PageSize = 0;
#endregion
#region 依赖属性
#region 数据源
public static readonly DependencyProperty PageSourceProperty =
DependencyProperty.RegisterAttached("PageSource", typeof(IEnumerable), typeof(PaginationAdorner),
new FrameworkPropertyMetadata(null, PageSourceCallback));
public static IEnumerable GetPageSource(DependencyObject obj)
{
return (IEnumerable)obj.GetValue(PageSourceProperty);
}
public static void SetPageSource(DependencyObject obj, IEnumerable value)
{
obj.SetValue(PageSourceProperty, value);
}
private static void PageSourceCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
PageSource = (IEnumerable)e.NewValue;
DrawData(d);
}
#endregion
#region DataGrid
public static readonly DependencyProperty PageDataGridProperty =
DependencyProperty.RegisterAttached("PageDataGrid", typeof(DataGrid), typeof(PaginationAdorner),
new FrameworkPropertyMetadata(null, PageDataGridCallback));
public static DataGrid GetPageDataGrid(DependencyObject obj)
{
return (DataGrid)obj.GetValue(PageDataGridProperty);
}
public static void SetPageDataGrid(DependencyObject obj, DataGrid value)
{
obj.SetValue(PageDataGridProperty, value);
}
private static void PageDataGridCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
dataGrid = (DataGrid)e.NewValue;
DrawData(d);
}
#endregion
#region 每页数量
public static readonly DependencyProperty PageSizeProperty =
DependencyProperty.RegisterAttached("PageSize", typeof(int), typeof(PaginationAdorner),
new FrameworkPropertyMetadata(0, PageSizeCallback));
public static int GetPageSize(DependencyObject obj)
{
return (int)obj.GetValue(PageSizeProperty);
}
public static void SetPageSize(DependencyObject obj, int value)
{
obj.SetValue(PageSizeProperty, value);
}
private static void PageSizeCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
PageSize = (int)e.NewValue;
DrawData(d);
}
#endregion
public static void DrawData(DependencyObject d)
{
if (PageSize != 0 && dataGrid != null && PageSource != null)
{
List<object> list = new();
foreach (var ones in PageSource)
{
list.Add(ones);
}
var source = d as FrameworkElement;
if (list.Count > PageSize)
{
//装饰件可用,添加装饰件
AdornerLayer layer = AdornerLayer.GetAdornerLayer(source);
if (layer != null)
{
Adorner[] AllAdorners = layer.GetAdorners(source);
if (AllAdorners != null)
{
IEnumerable<Adorner> desAdorners = AllAdorners.Where(p => p is PaginationAdorner);
if (desAdorners != null && desAdorners.Count() > 0)
{
desAdorners.ToList().ForEach(p => layer.Remove(p));
}
}
//能够获取装饰层,说明已经load过了,直接生成装饰件
var adorner = new PaginationAdorner(source);
layer.Add(adorner);
}
else
{
//layer为null,说明还未load过(整个可视化树中没有装饰层的情况不考虑)
//在控件的loaded事件内生成装饰件
source.Loaded += (s1, e1) =>
{
var adorner = new PaginationAdorner(source);
AdornerLayer.GetAdornerLayer(source).Add(adorner);
};
}
}
else
{
//装饰件不可用,移除装饰件
AdornerLayer layer = AdornerLayer.GetAdornerLayer(source);
if (layer != null)
{
Adorner[] AllAdorners = layer.GetAdorners(source);
if (AllAdorners != null)
{
IEnumerable<Adorner> desAdorners = AllAdorners.Where(p => p is PaginationAdorner);
if (desAdorners != null && desAdorners.Count() > 0)
{
desAdorners.ToList().ForEach(p => layer.Remove(p));
}
}
}
}
datagridPagination.ShowPages(dataGrid, list, PageSize);
}
}
#endregion
#region 样式
protected override int VisualChildrenCount
{
get { return 1; }
}
protected override Visual GetVisualChild(int index)
{
return datagridPagination;
}
protected override Size ArrangeOverride(Size arrangeBounds)
{
datagridPagination.Height = 30;
datagridPagination.VerticalContentAlignment = VerticalAlignment.Center;
datagridPagination.HorizontalAlignment = HorizontalAlignment.Stretch;
datagridPagination.VerticalAlignment = System.Windows.VerticalAlignment.Bottom;
datagridPagination.Arrange(new Rect(arrangeBounds));
return arrangeBounds;
}
#endregion
static DatagridPagination datagridPagination = new();
public PaginationAdorner(UIElement adornedElement) : base(adornedElement)
{
try
{
datagridPagination = new();
datagridPagination.DataContext = adornedElement;
this.AddVisualChild(datagridPagination);
}
catch (Exception ex)
{
}
}
}
Usercontrol样式:
<UserControl
x:Class="OSMS.Common.UserControls.DatagridPagination"
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:local="clr-namespace:OSMS.Common.UserControls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="50"
d:DesignWidth="800"
mc:Ignorable="d">
<UserControl.Resources>
<!-- 每页{0}/共{0}条 -->
<Style x:Key="PageTextBlock1" TargetType="{x:Type TextBlock}">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="FontSize" Value="13" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Foreground" Value="#FF333333" />
</Style>
<!-- 首页上一页等 -->
<Style x:Key="PageTextBlock2" TargetType="{x:Type TextBlock}">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="Margin" Value="5,0,5,0" />
<Setter Property="FontSize" Value="13" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Foreground" Value="#FF333333" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="#FF000000" />
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
</Style>
<!-- 中间页数 -->
<Style x:Key="PageTextBlock3" TargetType="{x:Type TextBlock}">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="Margin" Value="10,0,10,0" />
<Setter Property="FontSize" Value="13" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Foreground" Value="#FF333333" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="#FF000000" />
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="#FF000000" />
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="PageTextBox" TargetType="{x:Type TextBox}">
<Setter Property="Height" Value="20" />
<Setter Property="Margin" Value="5,0,5,0" />
<Setter Property="Width" Value="40" />
<Setter Property="BorderBrush" Value="{x:Null}" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="BorderBrush" Value="Black" />
<Style.Triggers>
<Trigger Property="IsReadOnly" Value="True">
<Setter Property="Background" Value="#FFCCCCCC" />
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="PageButton" TargetType="{x:Type Button}">
<Setter Property="Height" Value="20" />
<Setter Property="FontSize" Value="13" />
<Setter Property="Width" Value="30" />
<Setter Property="Margin" Value="0,0,0,0" />
<Setter Property="HorizontalAlignment" Value="Left" />
</Style>
</UserControl.Resources>
<StackPanel>
<Border Background="{x:Null}" CornerRadius="3">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<StackPanel
Height="30"
Margin="10,0,10,0"
HorizontalAlignment="Center"
Orientation="Horizontal">
<TextBlock
Name="btnFirst"
IsEnabled="False"
Style="{StaticResource PageTextBlock2}"
Text="首页" />
<TextBlock
Name="btnPrev"
IsEnabled="False"
Style="{StaticResource PageTextBlock2}"
Text="上一页" />
<Grid Name="grid" Grid.Column="2">
<Grid.RowDefinitions>
<RowDefinition Height="30" />
</Grid.RowDefinitions>
</Grid>
<TextBlock
x:Name="btnNext"
IsEnabled="False"
Style="{StaticResource PageTextBlock2}"
Text="下一页" />
<TextBlock
x:Name="btnLast"
IsEnabled="False"
Style="{StaticResource PageTextBlock2}"
Text="未页" />
<TextBox
x:Name="pageGo"
IsReadOnly="True"
MaxLength="6"
Style="{StaticResource PageTextBox}" />
<Button
x:Name="btnGo"
Content="GO"
IsEnabled="False"
Style="{StaticResource PageButton}" />
</StackPanel>
<TextBlock
Name="tbkRecords"
Grid.Column="1"
Margin="0,0,10,0"
HorizontalAlignment="Right"
Style="{StaticResource PageTextBlock1}"
Text="" />
</Grid>
</Border>
</StackPanel>
</UserControl>
cs文件:
public partial class DatagridPagination : UserControl
{
public DatagridPagination()
{
InitializeComponent();
this.Loaded += delegate
{
//首页
this.btnFirst.MouseLeftButtonUp += new MouseButtonEventHandler(btnFirst_Click);
this.btnFirst.MouseLeftButtonDown += new MouseButtonEventHandler(btnFirst_MouseLeftButtonDown);
//上一页
this.btnPrev.MouseLeftButtonUp += new MouseButtonEventHandler(btnPrev_Click);
this.btnPrev.MouseLeftButtonDown += new MouseButtonEventHandler(btnPrev_MouseLeftButtonDown);
//下一页
this.btnNext.MouseLeftButtonUp += new MouseButtonEventHandler(btnNext_Click);
this.btnNext.MouseLeftButtonDown += new MouseButtonEventHandler(btnNext_MouseLeftButtonDown);
//末页
this.btnLast.MouseLeftButtonUp += new MouseButtonEventHandler(btnLast_Click);
this.btnLast.MouseLeftButtonDown += new MouseButtonEventHandler(btnLast_MouseLeftButtonDown);
this.btnGo.Click += new RoutedEventHandler(btnGo_Click);
};
}
/// <summary>
/// 每页显示多少条
/// </summary>
private int pageNum = 10;
/// <summary>
/// 当前是第几页
/// </summary>
private int pIndex = 1;
/// <summary>
/// 对象
/// </summary>
private DataGrid grdList;
/// <summary>
/// 最大页数
/// </summary>
private int MaxIndex = 1;
/// <summary>
/// 一共多少条
/// </summary>
private int allNum = 0;
/// <summary>
/// 页面栏首页
/// </summary>
private int first = 0;
/// <summary>
/// 页面栏尾页
/// </summary>
private int last = 0;
/// <summary>
/// 数据集合
/// </summary>
List<System.Collections.IEnumerable> enumerables = new();
#region 初始化数据
public void ShowPages<T>(DataGrid grd, List<T> ds, int Num)
{
enumerables.Clear();
this.grdList = grd;
pageNum = Num;
if (ds.Count == 0)
{
this.grdList.ItemsSource = ds;
return;
}
this.MaxIndex = ds.Count / pageNum + ((ds.Count % pageNum) == 0 ? 0 : 1);
this.allNum = ds.Count;
for (int i = 0; i < MaxIndex; i++)
{
enumerables.Add(ds.Skip(i * pageNum).Take(pageNum));
}
ReadDataTable();
if (this.MaxIndex > 1)
{
this.pageGo.IsReadOnly = false;
this.btnGo.IsEnabled = true;
}
}
#endregion
#region 画数据
/// <summary>
/// 画数据
/// </summary>
private void ReadDataTable()
{
try
{
this.grdList.ItemsSource = enumerables[pIndex - 1];
}
catch
{
}
finally
{
DisplayPagingInfo();
}
}
#endregion
#region 画每页显示等数据
/// <summary>
/// 画每页显示等数据
/// </summary>
private void DisplayPagingInfo()
{
if (this.pIndex == 1)
{
this.btnPrev.IsEnabled = false;
this.btnFirst.IsEnabled = false;
}
else
{
this.btnPrev.IsEnabled = true;
this.btnFirst.IsEnabled = true;
}
if (this.pIndex == this.MaxIndex)
{
this.btnNext.IsEnabled = false;
this.btnLast.IsEnabled = false;
}
else
{
this.btnNext.IsEnabled = true;
this.btnLast.IsEnabled = true;
}
this.tbkRecords.Text = string.Format("[第{0}页/共{2}页][每页{1}条][共{3}条]", this.pIndex, this.pageNum, this.MaxIndex, this.allNum);
first = (this.pIndex - 2) <= 0 ? 1 : (this.pIndex + 2) > MaxIndex ? (MaxIndex - 4) : (this.pIndex - 2);
last = (first + 4) > this.MaxIndex ? this.MaxIndex : (first + 4);
DisplayData();
}
private void DisplayData()
{
this.grid.Children.Clear();
if (first != 1)
{
ColumnDefinition cdf = new ColumnDefinition();
this.grid.ColumnDefinitions.Add(cdf);
TextBlock tbleft = new TextBlock
{
Text = "<<",
Style = FindResource("PageTextBlock3") as Style
};
tbleft.MouseLeftButtonUp += new MouseButtonEventHandler(tbleft_MouseLeftButtonUp);
Grid.SetColumn(tbleft, this.grid.ColumnDefinitions.Count - 1);
Grid.SetRow(tbleft, 0);
this.grid.Children.Add(tbleft);
}
for (int i = first; i <= last; i++)
{
ColumnDefinition cdf = new ColumnDefinition();
this.grid.ColumnDefinitions.Add(cdf);
TextBlock tbl = new()
{
Text = i.ToString(),
Style = FindResource("PageTextBlock3") as Style
};
tbl.MouseLeftButtonUp += new MouseButtonEventHandler(tbl_MouseLeftButtonUp);
tbl.MouseLeftButtonDown += new MouseButtonEventHandler(tbl_MouseLeftButtonDown);
if (i == this.pIndex)
tbl.IsEnabled = false;
Grid.SetColumn(tbl, this.grid.ColumnDefinitions.Count - 1);
Grid.SetRow(tbl, 0);
this.grid.Children.Add(tbl);
}
if (last != MaxIndex)
{
ColumnDefinition cdf = new ColumnDefinition();
this.grid.ColumnDefinitions.Add(cdf);
TextBlock tbright = new TextBlock
{
Text = ">>",
Style = FindResource("PageTextBlock3") as Style
};
tbright.MouseLeftButtonUp += new MouseButtonEventHandler(tbright_MouseLeftButtonUp);
Grid.SetColumn(tbright, this.grid.ColumnDefinitions.Count - 1);
Grid.SetRow(tbright, 0);
this.grid.Children.Add(tbright);
}
}
private void tbright_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
first = (first + 5) > (MaxIndex - 5) ? (MaxIndex - 5) : (first + 5);
last = (last + 5) > MaxIndex ? MaxIndex : (last + 5);
DisplayData();
}
private void tbleft_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
first = (first - 5) > 1 ? 1 : (first - 5);
last = (last - 5) > 5 ? 5 : (last - 5);
DisplayData();
}
#endregion
#region 首页
/// <summary>
/// 首页
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnFirst_Click(object sender, System.EventArgs e)
{
this.pIndex = 1;
ReadDataTable();
}
/// <summary>
/// 首页
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnFirst_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
}
#endregion
#region 上一页
/// <summary>
/// 上一页
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnPrev_Click(object sender, System.EventArgs e)
{
if (this.pIndex <= 1)
return;
this.pIndex--;
ReadDataTable();
}
/// <summary>
/// 上一页
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnPrev_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
}
#endregion
#region 下一页
/// <summary>
/// 下一页
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnNext_Click(object sender, System.EventArgs e)
{
if (this.pIndex >= this.MaxIndex)
return;
this.pIndex++;
ReadDataTable();
}
/// <summary>
/// 下一页
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnNext_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
}
#endregion
#region 未页
/// <summary>
/// 未页
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnLast_Click(object sender, System.EventArgs e)
{
this.pIndex = this.MaxIndex;
ReadDataTable();
}
/// <summary>
/// 未页
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnLast_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
}
#endregion
#region 跳转到多少页
/// <summary>
/// 跳转到多少页
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnGo_Click(object sender, RoutedEventArgs e)
{
if (IsNumber(this.pageGo.Text))
{
int pageNum = int.Parse(this.pageGo.Text);
if (pageNum > 0 && pageNum <= this.MaxIndex)
{
this.pIndex = pageNum;
ReadDataTable();
}
else if (pageNum > this.MaxIndex)
{
this.pIndex = this.MaxIndex;
ReadDataTable();
}
}
this.pageGo.Text = "";
}
#endregion
#region 分页数字的点击触发事件
private void tbl_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
TextBlock tbl = sender as TextBlock;
if (tbl == null)
return;
int index = int.Parse(tbl.Text.ToString());
this.pIndex = index;
if (index > this.MaxIndex)
this.pIndex = this.MaxIndex;
if (index < 1)
this.pIndex = 1;
ReadDataTable();
}
void tbl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
}
#endregion
private static Regex RegNumber = new Regex("^[0-9]+$");
#region 判断是否是数字
/// <summary>
/// 判断是否是数字
/// </summary>
/// <param name="valString"></param>
/// <returns></returns>
public static bool IsNumber(string valString)
{
Match m = RegNumber.Match(valString);
return m.Success;
}
#endregion
}
DataGrid引用:
<DataGrid
x:Name="dgMain"
Grid.Row="2"
Margin="0,0,0,0"
datatemplateSelector:PaginationAdorner.PageDataGrid="{Binding ElementName=dgMain}"
datatemplateSelector:PaginationAdorner.PageSize="15"
datatemplateSelector:PaginationAdorner.PageSource="{Binding TrendDtoCollection}"
ItemsSource="{Binding TrendDtoCollection}"/>