做项目想到做一个数据分页显示的功能,网上也一大堆,但是我想一个人独立的思维完成这个功能,走了一些坑,导致思维有点混乱,一直没思路完成,最后在睡觉的时候重新整顿一下思路然后终于被我想通了,就这么干。自然是如愿以偿的完成想要的功能了。
1、用wpf制作,做成户控件能供别的页面也能使用。xaml如下:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="85"/>
<ColumnDefinition Width="74*"/>
<ColumnDefinition Width="202*"/>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="96"/>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="123*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="单页显示条数:" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="6,8,10,7" Height="16" Width="84" Foreground="Black"/>
<TextBox x:Name="TxtCutForm" Grid.Column="1" VerticalAlignment="Center" Margin="5,6,5,7" Height="18" />
<TextBlock Grid.Column="2" HorizontalAlignment="Left" VerticalAlignment="Center" Height="15" Margin="18,8,0,8" x:Name="BlockCount" Foreground="Black"></TextBlock>
<Button Grid.Column="4" Margin="5" Content="上一页" x:Name="BtnUp"></Button>
<TextBox x:Name="TxtPages" Grid.Column="5" VerticalAlignment="Center" Height="25" Margin="10,12,46,12" Text="1" VerticalContentAlignment="Center"/>
<TextBlock Grid.Column="5" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="61,8,29,7" Height="16" Width="6" Foreground="Black">/</TextBlock>
<TextBlock Grid.Column="5" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,8,7,7" Height="16" Width="7" Foreground="Black" x:Name="BlockPageCount">5</TextBlock>
<Button Grid.Column="6" Margin="5" Content="下一页" x:Name="BtnDown"></Button>
</Grid>
效果图:
2、整理一下思路:
具体思路将获取到的DataTable数据传入数据分页的交互逻辑代码进行处理,之后做返回当前也得数据,然后显示
3、实现:
添加一个设置文件,用来初始化当前页显示数据条数。
数据分页用户控件逻辑交互的代码处添加如下属性。SetData用来设置接收DataTable数据
public DataTable lstBuildingItem = new DataTable();
//用于接收DataTable数据
public DataTable SetData
{
set
{
lstBuildingItem = value;
lstDataCount = lstBuildingItem.Rows.Count;
BlockCount.Text = "共:" + lstDataCount + "条数据";
currentPageNum = "1";//初始化当前页
}
}
/// <summary>
/// 单页显示数据条数
/// </summary>
string cutFormNum
{
get { return TxtCutForm.Text; }
set
{
TxtCutForm.Text = value;
cutFormNumStr = TxtCutForm.Text;
}
}
string cutFormNumStr = string.Empty;
/// <summary>
/// 动态分页的数据条数
/// </summary>
int DataCountDynamic = 0;
/// <summary>
/// 当前页
/// </summary>
string currentPageNum
{
get { return TxtPages.Text; }
set
{
TxtPages.Text = value;
}
}
string currentPageNumStr = string.Empty;
/// <summary>
/// 总页数
/// </summary>
int pageCount = 0;
/// <summary>
/// 动态分页的数据条数
/// </summary>
int DataCountDynamic = 0;
添加初始化的函数
//构造函数
public FormC_Page()
{
InitializeComponent();
Initialize();
}
/// <summary>
/// 初始化
/// </summary>
private void Initialize()
{
BtnUp.Click += BtnUp_Click;//上一页点击事件
BtnDown.Click += BtnDown_Click;//下一页点击事件
cutFormNum = Properties.Setting.Default.PageCount;//初始化单页显示的数据条数(此为设置文件的值,需要添加设置文件)
cutFormNumStr = cutFormNum;
currentPageNumStr = currentPageNum;
TxtCutForm.TextChanged += TxtCutForm_TextChanged;//当页显示数据条数文框值改变事件
TxtPages.TextChanged += TxtPages_TextChanged;//当前页值文本框值改变事件
lstDataCount = lstBuildingItem.Rows.Count;
BlockCount.Text = "共:" + lstDataCount + "条数据";
}
添加一个上抛动作事件用于将数据传回去显示。
/// <summary>
/// 上抛动作属性:传递数据
/// </summary>
public event EventHandler<EventArgs> EvntFeedback;
添加设置分页的函数
/// <summary>
/// 设置分页
/// </summary>
public void SetPagingSetting()
{
DataTable lstTable = new DataTable();
if (lstDataCount == 0) return;
if (lstDataCount <= Convert.ToInt32(cutFormNum))
{
BlockPageCount.Text = "1";
lstTable = lstBuildingItem;
}
else
{
pageCount = (int)GetPaging(lstDataCount);//根据单页显示数据条数和数据总条数计算出共多少分页。
DataCountDynamic = Convert.ToInt32(cutFormNum);
BlockPageCount.Text = Math.Ceiling(((double)lstDataCount / DataCountDynamic)).ToString();
foreach (DataColumn item in lstBuildingItem.Columns)
{
string strCoulumnName = item.ColumnName;
lstTable.Columns.Add(item.ColumnName);
}
for (int i = 0; i < DataCountDynamic; i++)
{
lstTable.Rows.Add(lstBuildingItem.Rows[i].ItemArray);//
}
}
EvntFeedback?.Invoke(lstTable, null);//上抛事件是否为空,如果不为空则执行委托
}
/// <summary>
/// 根据数据条数和单页显示数据条数计算出共多少分页
/// </summary>
/// <param name="count">数据条数</param>
/// <returns></returns>
private double GetPaging(double count)
{
double index = 0;
index = count / Convert.ToInt32(cutFormNum);
if (index.ToString().Contains(".")) return Math.Ceiling(index);
return (int)index;
}
给SetData属性的Set添加设置分页函数
public DataTable SetData
{
set
{
lstBuildingItem = value;
lstDataCount = lstBuildingItem.Rows.Count;
BlockCount.Text = "共:" + lstDataCount + "条数据";
currentPageNum = "1";
SetPagingSetting();//
}
}
当前页值改变事件(核心)
/// <summary>
/// 当前页值文本框值改变事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void TxtPages_TextChanged(object sender, TextChangedEventArgs e)
{
//当前页
int currentPageNumFroInt = 0;
//单页显示数据条数
int cutFormNumInt = Convert.ToInt32(cutFormNum);
if (!CheckTxtCentent(sender))//判断当前页的值是否为数字且不等于0不大于总页数。
{
currentPageNum = currentPageNumStr;
return;
}
else
{
currentPageNumFroInt = Convert.ToInt32(currentPageNum);
if (currentPageNumFroInt > pageCount)
{
currentPageNum = currentPageNumStr;
return;
}
currentPageNumStr = currentPageNum;
DataTable lstTable = new DataTable();
int IndexNumber = (cutFormNumInt * currentPageNumFroInt) - cutFormNumInt;
//如果当前页等于最大页数
if (currentPageNumFroInt == pageCount)
{
//int number = Convert.ToInt32(cutFormNum) * currentPageNumFroInt - (lstDataCount / currentPageNumFroInt);
int getRidOfEndPageCount = (pageCount - 1) * cutFormNumInt;//获取除最后页的数据条数的所有数据条数
int endPageCount = lstDataCount - getRidOfEndPageCount;//获取到最后一页的数据条数。
lstTable = SetLstDataRows(endPageCount, lstTable, IndexNumber);
}
else
{
lstTable = SetLstDataRows(cutFormNumInt, lstTable, IndexNumber);
}
EvntFeedback?.Invoke(lstTable, null);//事件为空跳过事件。
}
}
/// <summary>
/// 设置显示数据
/// </summary>
private DataTable SetLstDataRows(int count,DataTable lstTable,int index = 0)
{
foreach (DataColumn item in lstBuildingItem.Columns)
{
string strCoulumnName = item.ColumnName;
lstTable.Columns.Add(item.ColumnName);
}
for (int i = 0; i < count; i++)
{
lstTable.Rows.Add(lstBuildingItem.Rows[index].ItemArray);
index++;
}
return lstTable;
}
下or上一页点击事件
/// <summary>
/// 下一页
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BtnDown_Click(object sender, RoutedEventArgs e)
{
PageChanged(false);
}
/// <summary>
/// 上一页
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BtnUp_Click(object sender, RoutedEventArgs e)
{
PageChanged(true);
}
void PageChanged(bool isUpOrDow)
{
if (Tools.Function.CommonFunction.JudgeInt(TxtPages.Text.Trim()))
{
int number = Convert.ToInt32(TxtPages.Text.Trim());
int PageNumber = Convert.ToInt32(currentPageNum);
if (isUpOrDow)//上一页
{
if (number == 1) return;
PageNumber--;
}
else
{//下一页
if (number == Convert.ToInt32(BlockPageCount.Text)) return;
PageNumber++;
}
currentPageNum = PageNumber.ToString();//此处会触发当前页值改变事件。
}
}
当页显示数据条数文框值改变事件
/// <summary>
/// 当页显示数据条数文框值改变事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TxtCutForm_TextChanged(object sender, TextChangedEventArgs e)
{
if (!CheckTxtCentent(sender))//检查是否为数字并且不等于0,可以上网自己找各种方法,这里就不方出来了。
cutFormNum = cutFormNumStr;
else
{
TxtPages.Text = "1";
cutFormNumStr = cutFormNum;
SetPagingSetting();//设置分页函数
}
}
4调用。
在需调用的窗体实例化该分页功能的用户控件
FormC_Page formC_Page = new FormC_Page();//分页控件
form_Page.SetData = dataTable;//dataTable数据
GridPage.Children.Add(formC_Page);
注册上抛事件。
formC_Page.EvntFeedback += FormC_Page_EvntFeedback;//数据上抛
private void FormC_Page_EvntFeedback(object sender, EventArgs e)
{
DataTable data = sender as DataTable;
DGBuilding.ItemsSource = data.DefaultView;
}
将数据传给数据分页控件,
formC_Page.SetData = lstBuildingItem;
完成
5效果图
结语:
至于还有没有别的bug尚未的得知,当我已经比较满足了,对于我来说完全够用了,当然这只适合轻量应用,数据以多起来可能就会有卡慢现象了。到时候在想一个比较好优化一点的。