纯新手,以下文章只为整理思路,记录一下。
思路如下:
1.在数据库中创建一个可以得到一定量数据的存储过程。
2.在winform应用程序下调用它,得到这个数据集,调用数据集,用代码根据数据自动生成控件。
创建储存过程
加一个小判断方便重复生成
if exists(select * from sysobjects where name='pro_getdata')
drop procedure pro_getdata
go
create proc pro_getdata
首先先要声明3个变量:
pageCurrent(用于储存当前用户选择页)
pageSize(规定每页有多少条数据)
pageCount(用于储存总页数,这是一个输出参数)
@pageCurrent int,--当前页数
@pageSize int,--每页的大小
@pageCount int out--总页数 输出参数
然后给pageCount总页数赋值。
先用select获取到表中的总行数付给pagecount
再将,总行数/=每页的大小
就能够得到总页数了
select @pageCount=count(*) from Books
set @pageCount/=20
好了,就剩下最后一步获取数据了。
首先我们,我们获取数据的话,肯定不能全部一次性,全部获取。必须分批次获取,才对,那么就会存在一个上限值和一个下限值。
但是,直接用主键的话会有一些问题,而且我们得考虑到数据丢失的问题。
如果某一页需要20条数据才能算一页,假如先提取范围规定到1-20的二十条数据,而第15条数据被删除的话,用主键获取的数据将会只有19条,明显没有满足这个每页有20条数据要求。
所以在这里可以用到 ROW_NUMBER()这个排序函数就解决这个问题
select ROW_NUMBER() over(order by 主键名) from 表名
剩下 的就简单了,我们只需要将ROW_NUMBER()函数获取到的列做为查询数据的条件就ok了
select a.row,a.Title,a.Author,a.UnitPrice from (
select ROW_NUMBER() over(order by Id) as row,* from Books) as a where a.row between 1 and 20
当然,上面只是获取1到20的数据集,我们还得根据用户选择的当前页来得到数据。
select a.row,a.Title,a.Author,a.UnitPrice from (
select ROW_NUMBER() over(order by Id) as row,* from Books) as a where a.row between (@pageCurrent-1)*@pageSize+1 and (@pageCurrent*@pageSize)
结合起来就是
if(@pageCurrent=1)
begin
select a.row,a.Title,a.Author,a.UnitPrice from (
select ROW_NUMBER() over(order by Id) as row,* from Books) as a where a.row between 1 and 20
end
else
begin
select a.row,a.Title,a.Author,a.UnitPrice from (
select ROW_NUMBER() over(order by Id) as row,* from Books) as a where a.row between (@pageCurrent-1)*@pageSize+1 and (@pageCurrent*@pageSize)
end
以下是完整代码
// sql server数据库创建存储过程
if exists(select * from sysobjects where name='pro_getdata')
drop procedure pro_getdata
go
create proc pro_getdata
@pageCurrent int,--当前页数
@pageSize int,--每页的大小
@pageCount int out--总页数 输出参数
as
select @pageCount=count(*) from Books
set @pageCount/=20
if(@pageCurrent=1)
begin
select a.row,a.Title,a.Author,a.UnitPrice from (
select ROW_NUMBER() over(order by Id) as row,* from Books) as a where a.row between 1 and 20
end
else
begin
select a.row,a.Title,a.Author,a.UnitPrice from (
select ROW_NUMBER() over(order by Id) as row,* from Books) as a where a.row between (@pageCurrent-1)*@pageSize+1 and (@pageCurrent*@pageSize)
end
先创建一个操作数据库的类
在里面写一个调用存储过程的方法
///
/// 调用存储过程的方法
///
/// 总页数
/// 当前选择页
/// 每页大小
///
public DataTable GetData1(out int page_count,int page_current,int page_size)
{
DataTable dt = new DataTable();
con.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "pro_getdata";
cmd.Parameters.Add(new SqlParameter("@pageCurrent", page_current));
cmd.Parameters.Add(new SqlParameter("@pageSize", page_size));
SqlParameter parameter = new SqlParameter("@pageCount", SqlDbType.Int);
parameter.Direction = ParameterDirection.Output;
cmd.Parameters.Add(parameter);
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
page_count = (int)parameter.Value;
con.Close();
return dt;
}
再回到分页窗体这里来
声明3个全局变量,并实例化操作数据的类
int count = 0;
int page_current = 1;
int page_size = 20;
sqldb sqldb = new sqldb();
再写一个自动生成控件的方法
方法里面用变量dt储存得到的数据集
private void auto_Contr()
{
this.Controls.Clear();
DataTable dt = sqldb.GetData1(out count, page_current, page_size);
int x = 0;
int y = 0;
foreach(DataRow dr in dt.Rows)
{
Panel pl = new Panel();
pl.BorderStyle = BorderStyle.Fixed3D;
pl.Size = new Size(180, 230);
PictureBox box = new PictureBox();
box.ImageLocation = @"D:\作业\image\timg.jpg";
box.SizeMode = PictureBoxSizeMode.StretchImage;
box.Width = 180;
box.Height = 150;
pl.Controls.Add(box);
box.Location = new Point(0, 0);
Label lbl_bookname = new Label();
lbl_bookname.Text = dr["Title"].ToString();
lbl_bookname.ForeColor = Color.Blue;
lbl_bookname.Size = new Size(180, 15);
pl.Controls.Add(lbl_bookname);
lbl_bookname.Location = new Point(0, 150);
Label lbl_writer = new Label();
lbl_writer.Text = dr["Author"].ToString();
lbl_writer.Size = new Size(180, 15);
pl.Controls.Add(lbl_writer);
lbl_writer.Location = new Point(0, 180);
Label lbl_price = new Label();
lbl_price.Text = "¥" + dr["UnitPrice"].ToString();
lbl_price.ForeColor = Color.FromArgb(177,39,95);
pl.Controls.Add(lbl_price);
lbl_price.Location = new Point(0, 210);
pl.Location = new Point(x,y);
this.Controls.Add(pl);
x += 200;
if(x>=1000)
{
x = 0;
y += 250;
}
}
Panel pl2 = new Panel();
pl2.Size = new Size(count * 30, 30);
pl2.Location = new Point(this.Width / 2, y);
x = 0;
y = 0;
int ii = 0;
for (int i= page_current>3 ? page_current - 3 :1; i<=count;i++)
{
Button btn = new Button();
btn.Text = (i).ToString();
btn.Click += Btn_Click;
btn.Size = new Size(30, 30);
if(i==page_current)
{
btn.BackColor = Color.FromArgb(231, 118, 0);
}
else
{
btn.BackColor = Color.FromArgb(239, 240, 243);
}
btn.Location = new Point(x+=40,y);
pl2.Controls.Add(btn);
if(ii>7)
{
break;
}
ii++;
}
this.Controls.Add(pl2);
}
以下是换页按钮绑定的方法
private void Btn_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
int btn_page = int.Parse( btn.Text);
if(page_current-btn_page>0)
{
//后退页
page_current = btn_page;
auto_Contr();
}
else
{
//前进页
page_current = btn_page;
auto_Contr();
}
}
最终实现的模样
潜水这么久了,终于写了一次有自己的文章,这是第一次,希望也不是我的最后一次
实例项目附数据库:https://download.csdn.net/download/weixin_43851854/11750616