开发环境:Visual Studio 2010
如果说你还在用Visual Studio 2005,那么你应该知道没有ListView和Entity这两个东东。
如果说你还在用Visual Studio 2008,应该就没什么不同了。
首先,完成DataPager的自定义分页模板,写到自定义控件吧,虽然说没效果没真相,但我相信你懂的:
Html:
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="LVDataPager.ascx.cs" Inherits="Ascx_LVDataPager" %>
<asp:DataPager ID="DP" runat="server" OnInit="DP_Init">
<Fields>
<asp:TemplatePagerField OnPagerCommand="PagerField_OnPagerCommand">
<PagerTemplate>
共
<asp:Label ID="LabelTotalRecordCount" runat="server" Text="<%# InnerTotalRecord %>"
Style="color: #aa0c39"></asp:Label>
条记录 当前第:
<asp:Label ID="LabelCurrentPage" runat="server" Style="color: #aa0c39"
Text="<%# (((DataPager)Container).StartRowIndex/((DataPager)Container).PageSize)+1 %>">
</asp:Label>
/
<asp:Label ID="LabelPageCount" runat="server" Style="color: #aa0c39"
Text="<%# ((((DataPager)Container).TotalRowCount-1)/((DataPager)Container).PageSize)+1 %>">
</asp:Label>
页
<asp:LinkButton ID="LinkButtonFirstPage" runat="server" CommandArgument="First"
CommandName="First" Visible='<%#((DataPager)Container).StartRowIndex != 0 %>'>
首页
</asp:LinkButton>
<asp:LinkButton ID="LinkButtonPreviousPage" runat="server" CommandArgument="Prev"
CommandName="Prev" Visible='<%# ((DataPager)Container).StartRowIndex != 0 %>'>
前一页
</asp:LinkButton>
<asp:LinkButton ID="LinkButtonNextPage" runat="server" CommandArgument="Next"
CommandName="Next"
Visible='<%#
(((DataPager)Container).StartRowIndex/((DataPager)Container).PageSize)+1 !=
((((DataPager)Container).TotalRowCount-1)/((DataPager)Container).PageSize)+1
%>'>
后一页
</asp:LinkButton>
<asp:LinkButton ID="LinkButton1" runat="server" CommandArgument="Last" CommandName="Last"
Visible='<%#
(((DataPager)Container).StartRowIndex/((DataPager)Container).PageSize)+1 !=
((((DataPager)Container).TotalRowCount-1)/((DataPager)Container).PageSize)+1 %>'>
尾页
</asp:LinkButton>
转到第
<asp:TextBox ID="txtNewPageIndex" runat="server" Width="20px"
Text='<%# (((DataPager)Container).StartRowIndex/((DataPager)Container).PageSize)+1 %>' />
页
<asp:LinkButton ID="btnGotoPage" runat="server" CausesValidation="False"
CommandArgument="-1" CommandName="PageTrans">go</asp:LinkButton>
</PagerTemplate>
</asp:TemplatePagerField>
</Fields>
</asp:DataPager>
C# Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class Ascx_LVDataPager : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
public string InnerListView
{
get { return DP.PagedControlID; }
set { DP.PagedControlID = value; }
}
public int InnerPageSize
{
get { return DP.PageSize; }
set { DP.PageSize = value; }
}
public int InnerTotalRecord
{
get{return DP.TotalRowCount;}
}
protected void DP_Init(object sender, EventArgs e)
{
DataPager dp = (DataPager)sender;
dp.PagedControlID = InnerListView;
dp.PageSize = InnerPageSize;
}
protected void PagerField_OnPagerCommand(object sender, DataPagerCommandEventArgs e)
{
switch (e.CommandName)
{
case "Next":
int newIndex = e.Item.Pager.StartRowIndex + e.Item.Pager.PageSize;
if (newIndex <= e.TotalRowCount)
{
e.NewStartRowIndex = newIndex;
e.NewMaximumRows = e.Item.Pager.MaximumRows;
}
break;
case "Last":
{
int pageCount = (e.TotalRowCount - 1) / e.Item.Pager.PageSize;
e.NewStartRowIndex = pageCount * e.Item.Pager.PageSize;
e.NewMaximumRows = e.Item.Pager.MaximumRows;
}
break;
case "Prev":
e.NewStartRowIndex = e.Item.Pager.StartRowIndex - e.Item.Pager.PageSize;
e.NewMaximumRows = e.Item.Pager.MaximumRows;
break;
case "First":
e.NewStartRowIndex = 0;
e.NewMaximumRows = e.Item.Pager.MaximumRows;
break;
case "PageTrans":
TextBox txtNewPageIndex = (TextBox)e.Item.FindControl("txtNewPageIndex");
if (txtNewPageIndex.Text != "")
{
int transPage;
try
{
transPage = int.Parse(txtNewPageIndex.Text);
}
catch
{
return;
}
int pageCount = (e.TotalRowCount - 1) / e.Item.Pager.PageSize + 1;
if (transPage > 0 && transPage <= pageCount)
{
e.NewStartRowIndex = (transPage - 1) * e.Item.Pager.PageSize;
e.NewMaximumRows = e.Item.Pager.MaximumRows;
}
else
{
txtNewPageIndex.Text = (e.Item.Pager.StartRowIndex / e.Item.Pager.PageSize + 1).ToString();
}
}
break;
}
}
}
哎呀,自定义分页就是代码量多,你说要是把代码都放到页面里去,放到每个页面里去,多不好啊。好了,接下来是ListView + ObjectDataSource + Entity
如果说,你没有弄过Entity,那么你就拼接Sql吧!
ListView:
<%@ Page Title="" Language="C#" MasterPageFile="~/System/System.master" AutoEventWireup="true"
CodeFile="UserList.aspx.cs" Inherits="System_UserList" %>
<%@ Register Src="~/ascx/LVDataPager.ascx" TagName="LVDataPager" TagPrefix="uc1" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="CPH" runat="Server">
<asp:ScriptManager runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UPSearch" runat="server">
<ContentTemplate>
<table>
<tr>
<td>
<asp:Label ID="lblUserName" runat="server" Text="用户名称"></asp:Label>
</td>
<td>
<asp:TextBox ID="txtUserName" runat="server"></asp:TextBox>
</td>
<td>
<asp:Label ID="lblCreateTime" runat="server" Text="创建时间"></asp:Label>
</td>
<td>
从<asp:TextBox ID="txtFrom" runat="server"></asp:TextBox>
到<asp:TextBox ID="txtTo" runat="server"></asp:TextBox>
</td>
<td>
<asp:Button ID="btnSearch" runat="server" Text="查询" />
</td>
</tr>
</table>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdatePanel ID="UPList" runat="server">
<ContentTemplate>
<asp:ListView ID="LV" runat="server" DataKeyNames="UserID" DataSourceID="ODS">
<LayoutTemplate>
<table id="itemPlaceholderContainer" runat="server">
<tr>
<th>
UserID
</th>
<th>
UserName
</th>
<th>
CreateTime
</th>
</tr>
<tr id="itemPlaceholder" runat="server">
<td runat="server">
</td>
</tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td>
<asp:Label ID="UserIDLabel" runat="server" Text='<%# Eval("UserID") %>' />
</td>
<td>
<asp:Label ID="UserNameLabel" runat="server" Text='<%# Eval("UserName") %>'/>
</td>
<td>
<asp:Label ID="CreateTimeLabel" runat="server" Text='<%# Eval("CreateTime") %>'></asp:Label>
</td>
</tr>
</ItemTemplate>
<EmptyDataTemplate>
<tr>
<td>
未返回数据。
</td>
</tr>
</EmptyDataTemplate>
</asp:ListView>
</ContentTemplate>
</asp:UpdatePanel>
<uc1:LVDataPager ID="LVDP" InnerListView="LV" runat="server" />
<asp:ObjectDataSource ID="ODS" runat="server" SelectMethod="LoadData" DataObjectTypeName="JC.DB.Web.JC_Users"
TypeName="System_UserList" EnablePaging="True" MaximumRowsParameterName="maxRows"
StartRowIndexParameterName="startIndex" SelectCountMethod="CountAll">
<SelectParameters>
<asp:Parameter Type="String" Name="strWhere" />
</SelectParameters>
</asp:ObjectDataSource>
</asp:Content>
看了上面的代码,不知道你会不会晕,别急,容我解释,页面我是用了母版页,那么母版页是神马,你就别管了,没啥用。ListView就随便给了三个字段,简单为要嘛。ObjectDataSource的配置是浮云,就等上了后台代码再解释了。
C# 代码:
暂时不写,上班中……最后一天上班,整个公司只有自己在上班,乱来了,继续继续。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class System_UserList : System.Web.UI.Page
{
/// <summary>
/// 数据对象
/// </summary>
public List<JC.DB.Web.JC_Users> list = null;
/// <summary>
/// 每页数量
/// </summary>
private int PageSize = 18;
protected void Page_Load(object sender, EventArgs e)
{
//是网站的就一定要加这句啦,然后每次PostBack也要执行,Web应用程序就不用了。
ODS.TypeName = this.GetType().FullName + "," + this.GetType().Assembly.FullName;
//设置分页数量
LVDP.InnerPageSize = PageSize;
if (!IsPostBack)
{
}
}
/// <summary>
/// 拼接搜索条件
/// </summary>
/// <returns></returns>
private string BuildSearchCondition()
{
string Condition = string.Empty;
Condition += (" 1 = 1 ");
//用户
if (!string.IsNullOrWhiteSpace(txtUserName.Text))
{
Condition += string.Format(" and it.UserName like '%{0}%' ", txtUserName.Text.Trim());
}
//开始日期
if (!string.IsNullOrWhiteSpace(txtFrom.Text))
{
DateTime dtSearchDateStart;
try
{
dtSearchDateStart = Convert.ToDateTime(txtFrom.Text.Trim());
Condition += string.Format(" and it.CreateTime >= datetime'{0}' ", dtSearchDateStart.ToString("yyyy-MM-dd HH:mm:ss"));
}
catch
{
txtFrom.Text = "";
return string.Empty;
}
}
//结束日期
if (!string.IsNullOrWhiteSpace(txtTo.Text))
{
DateTime dtSearchDateEnd;
try
{
dtSearchDateEnd = Convert.ToDateTime(txtTo.Text.Trim());
Condition += string.Format(" and it.CreateTime < datetime'{0}' ", dtSearchDateEnd.AddDays(1).ToString("yyyy-MM-dd HH:mm:ss"));
}
catch
{
txtTo.Text = "";
return string.Empty;
}
}
return Condition;
}
/// <summary>
/// 设置参数:将搜索条件作为一个字符串参数放入到ObjectDataSource
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void ODS_Selecting(object sender, ObjectDataSourceSelectingEventArgs e)
{
e.InputParameters["strWhere"] = BuildSearchCondition();
}
/// <summary>
/// 返回符合条件的总数
/// </summary>
/// <param name="strWhere"></param>
/// <returns></returns>
public int CountAll(string strWhere)
{
if (strWhere == string.Empty)
{
return 0;
}
using (JC.DB.Web.Entities entities = new JC.DB.Web.Entities())
{
return entities.JC_Users.Where(strWhere).Count();
}
}
/// <summary>
/// 加载数据
/// </summary>
/// <param name="startIndex"></param>
/// <param name="maxRows"></param>
/// <param name="strWhere"></param>
/// <returns></returns>
public List<JC.DB.Web.JC_Users> LoadData(int startIndex, int maxRows, string strWhere)
{
if (strWhere == string.Empty)
{
return null;
}
using (JC.DB.Web.Entities entities = new JC.DB.Web.Entities())
{
return entities.JC_Users.Where(strWhere).OrderBy(it => it.UserID).Skip(startIndex).Take(maxRows).ToList();
}
}
/// <summary>
/// 刷新
/// </summary>
private void RefreshData()
{
LV.DataSourceID = ODS.ID;
}
/// <summary>
/// 查询
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void btnSearch_Click(object sender, EventArgs e)
{
RefreshData();
UPList.Update();
}
}
好了,又贴上了一堆浮云,需要解释不,高手是不需要解释的,放过小弟吧,小弟才疏学浅,拿着微薄的薪水糊口饭而已,别向我砸石头啦!我还是讲解下吧。
<asp:ObjectDataSource ID="ODS" runat="server" SelectMethod="LoadData" DataObjectTypeName="JC.DB.Web.JC_Users"
TypeName="System_UserList" EnablePaging="True" MaximumRowsParameterName="maxRows"
StartRowIndexParameterName="startIndex" SelectCountMethod="CountAll">
<SelectParameters>
<asp:Parameter Type="String" Name="strWhere" />
</SelectParameters>
</asp:ObjectDataSource>
SelectMethod:
指定用于获取分页数据的方法名。这个方法是一个自定义的.NET方法,你可以写在页面的CodeBehind代码中,将方法的名字给ObjectDataSource控件的SelectMethod即可。ObjectDataSource控件会通过委托的方式自动去执行你所指定的这个方法。
TypeName:
使用ObjectDataSource控件的类的全名称(包括名称空间和类名)。这个属性必须指定,ASP.NET会通过反射来加载相应的方法和对象。
DataObjectTypeName:
数据源对象的类型全名称。ObjectDataSource控件最大的亮点就在于它完全支持面向对象数据操作。在分层应用程序开发中,数据访问层的代码会将数据库中的表抽象为class对象,将数据库表中的字段抽象为class对象中的属性,DataObjectTypeName属性所指定的就是这个数据库类对象。
EnablePaging:
如果你想开启数据分页功能,就需要将这个属性的值设置为True。
MaximumRowsParameterName:
这个属性的值是一个参数名(只是一个参数名,而不是每页显示的数据条数),用于指示每页要显示数据的条数,ObjectDataSource控件根据委托在之前SelectMethod属性所指定的方法中传递该参数并执行其中的代码。注意,这个参数的名称必须与SelectMethod属性所指定的方法中的参数名称完全一样。
StartRowIndexParameterName:
这个属性也是一个参数名,用于指示每页起始记录的索引。用法与MaximumRowsParameterName相同。
SelectCountMethod:
这个属性是一个方法的签名,用来告诉ObjectDataSource控件通过什么方式得知数据源中总记录的条数。ObjectDataSource控件同样通过委托来执行这个方法,所以方法的签名必须与属性的值完全一样。
贴完了休息下,稍等有个精华的图片给你瞧瞧……
来了来了……
这种是ObjectDataSource的处理原理,如果说,你在ObjectDataSource的事件里头,发现页面上的控件值全部为Null的时候,看到上面这张图的时候,也许你就会恍然大悟了。做人还是厚道点,把参考链接附上,反正我就只看这张图片,其他没理(http://www.asp.net/web-forms/tutorials/data-access/basic-reporting/programmatically-setting-the-objectdatasource-s-parameter-values-cs)
最后呢,你问我还有GridView的呢。哎呀,我只是告诉你GridView照样可以这样用,分页模板也可以写到自定义控件里头去,我可不会像YYControl那样,自己扩展个Gridview,一来我的《庖丁解牛》还没看完,而来技术能力有限。至于你在GridView的分页模板中要获取符合查询条件的数据的总条数的时候,也许会遇到问题,那么偶也贴个代码出来,或许你能得到什么提示。
protected void ODS_SWOT_Selected(object sender, ObjectDataSourceStatusEventArgs e)
{
//此处运行两次,第一次e.ReturnValue = SelectMethod,第二次 e.ReturnValue = SelectCountMethod
if (e.ReturnValue is int)
TotalSWOTRecordCount = (int)e.ReturnValue;
}
如果是菜鸟的话,别问我,我三天打鱼两天晒网,很少来博客,看我博客里头的内容就知道了,半年来一次。高手自己不用问啦。
好吧!最后诚恳点,有人给我留言那将会是一件很幸福的事情。