DataGrid技巧大全

QQ:16441708

MSN:Baconxu@hotmail.com 

 

2006-3-30
当前行的背景色 [ ]
Private Sub DataGrid1_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles DataGrid1.ItemDataBound
        If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then
            '
添加自定义属性,当鼠标移过来时设置该行的背景色为 "#eaeaea", 并保存原背景色
            e.Item.Attributes.Add("onmouseover", "currentcolor=this.style.backgroundColor;this.style.backgroundColor='#eaeaea'"
            '
添加自定义属性,当鼠标移走时还原该行的背景色
            e.Item.Attributes.Add("onmouseout", "this.style.backgroundColor=currentcolor"
        End If
    End Sub
loading...
 
 
2006-3-17
asp.net 常用函数 [ ]
Abs(number) 取得数值的绝对值。
Asc(String)
取得字符串表达式的第一个字符 ASCII 码。
Atn(number)
取得一个角度的反正切值。
CallByName (object, procname, usecalltype,[args()])
执行一个对象的方法、设定或传回对象的属性。
CBool(expression)
转换表达式为 Boolean 型态。
CByte(expression)
转换表达式为 Byte 型态。
CChar(expression)
转换表达式为字符型态。
CDate(expression)
转换表达式为 Date 型态。
CDbl(expression)
转换表达式为 Double 型态。
CDec(expression)
转换表达式为 Decimal 型态。
CInt(expression)
转换表达式为 Integer 型态。
CLng(expression)
转换表达式为 Long 型态。
CObj(expression)
转换表达式为 Object 型态。
CShort(expression)
转换表达式为 Short 型态。
CSng(expression)
转换表达式为 Single 型态。
CStr(expression)
转换表达式为 String 型态。
Choose (index, choice-1[, choice-2, ... [, choice-n]])
以索引值来选择并传回所设定的参数。
Chr(charcode)
ASCII 码来取得字符内容。
Close(filenumberlist)
结束使用 Open 开启的档案。
Cos(number)
取得一个角度的余弦值。
Ctype(expression, typename)
转换表达式的型态。
DateAdd(dateinterval, number, datetime)
对日期或时间作加减。
DateDiff(dateinterval, date1, date2)
计算两个日期或时间间的差值。
DatePart (dateinterval, date)
依接收的日期或时间参数传回年、月、日或时间。
DateSerial(year, month, day)
将接收的参数合并为一个只有日期的 Date 型态的数据。
DateValue(datetime)
取得符合国别设定样式的日期值,并包含时间。
Day(datetime)
依接收的日期参数传回日。
Eof(filenumber)
当抵达一个被开启的档案结尾时会传回 True
Exp(number)
依接收的参数传回 e 的次方值。
FileDateTime(pathname)
传回档案建立时的日期、时间。
FileLen(pathname)
传回档案的长度,单位是 Byte
Filter(sourcearray, match[, include[, compare]])
搜寻字符串数组中的指定字符串,凡是数组元素中含有指定字符串,会将它们结合成新的字符串数组并传回。若是要传回不含指定字符串的数组元素,则 include 参数设为 False compare 参数则是设定搜寻时是否区分大小写,此时只要给 TextCompare 常数或 1 即可。
Fix(number)
去掉参数的小数部分并传回。
Format(expression[, style[, firstdayofweek[, firstweekofyear]]])
将日期、时间和数值资料转为每个国家都可以接受的格式。
FormatCurrency(expression[,numdigitsafterdecimal [,includeleadingdigit]])
将数值输出为金额型态。 numdigitsafterdecimal 参数为小数字数, includeleadingdigit 参数为当整数为 0 时是否补至整数字数。
FormatDateTime(date[,namedformat])
传回格式化的日期或时间数据。
FormatNumber(expression[,numdigitsafterdecimal [,includeleadingdigit]])
传回格式化的数值数据。 Numdigitsafterdecimal 参数为小数字数, includeleadingdigit 参数为当整数为 0 时是否补至整数字数。
FormatPercent(expression[,numdigitsafterdecimal [,includeleadingdigit]])
传回转换为百分比格式的数值数据。 numdigitsafterdecimal 参数为小数字数 ,includeleadingdigit 参数为当整数为 0 时是否补至整数字数。
GetAttr(filename)
传回档案或目录的属性值。
Hex(number)
将数值参数转换为 16 进制值。
Hour(time)
传回时间的小时字段,型态是 Integer
Iif(expression, truepart, falsepart)
当表达式的传回值为 True 时执行 truepart 字段的程序,反之则执行 falsepart 字段。
InStr([start, ]string1, string2)
搜寻 string2 参数设定的字符出现在字符串的第几个字符, start 为由第几个字符开始寻找, string1 为欲搜寻的字符串, string2 为欲搜寻的字符。
Int(number)
传回小于或等于接收参数的最大整数值。
IsArray(varname)
判断一个变量是否为数组型态,若为数组则传回 True ,反之则为 False
IsDate(expression)
判断表达式内容是否为 DateTime 型态,若是则传回 True ,反之则为 False
IsDbNull(expression)
判断表达式内容是否为 Null ,若是则传回 True ,反之则为 False
IsNumeric(expression)
判断表达式内容是否为数值型态,若是则传回 True ,反之则为 False
Join(sourcearray[, delimiter])
将字符串数组合并唯一个字符串, delimiter 参数是设定在各个元素间加入新的字符串。
Lcase(string)
将字符串转换为小写字体。
Left(string, length)
由字符串左边开始取得 length 参数设定长度的字符。
Len(string)
取得字符串的长度。
Log(number)
取得数值的自然对数。
Ltrim(string)
去掉字符串的左边空白部分。
Mid(string, start[, length])
取出字符串中 strat 参数设定的字符后 length 长度的字符串,若 length 参数没有设定,则取回 start 以后全部的字符。
Minute(time)
取得时间内容的分部分,型态为 Integer
MkDir(path)
建立一个新的目录。
Month(date)
取得日期的月部分,型态为 Integer
MonthName(month)
依接收的月份数值取得该月份的完整写法。
Now()
取得目前的日期和时间。
Oct(number)
将数值参数转换为 8 进制值。
Replace(expression, find, replace)
将字符串中 find 参数指定的字符串转换为 replace 参数指定的字符串。
Right(string,length)
由字符串右边开始取得 length 参数设定长度的字符。
RmDir(path)
移除一个空的目录。
Rnd()
取得介于 0 1 之间的小数,如果每次都要取得不同的值,使用前需加上 Randomize 叙述。
Rtrim(string)
去掉字符串的右边空白部分。
Second(time)
取得时间内容的秒部分,型态为 Integer
Sign(number)
取得数值内容是正数或负数,正数传回 1 ,负数传回 -1 0 传回 0
Sin(number)
取得一个角度的正弦值。
Space(number)
取得 number 参数设定的空白字符串。
Split(expression[, delimiter])
delimiter 参数设定的条件字符串来将字符串分割为字符串数组。
Sqrt(number)
取得一数值得平方根。
Str(number)
将数字转为字符串后传回。
StrReverse(expression)
取得字符串内容反转后的结果。
Tan(number)
取得某个角度的正切值。
TimeOfDay()
取得目前不包含日期的时间。
Timer()
取得由 0:00 到目前时间的秒数,型态为 Double
TimeSerial(hour, minute, second)
将接收的参数合并为一个只有时间 Date 型态的数据。
TimaValue(time)
取得符合国别设定样式的时间值。
Today()
取得今天不包含时间的日期。
Trim(string)
去掉字符串开头和结尾的空白。
TypeName(varname)
取得变量或对象的型态。
Ubound(arrayname[, dimension])
取得数组的最终索引值, dimension 参数是指定取得第几维度的最终索引值。
Ucase(string)
将字符串转换为大写。
Val(string)
将代表数字的字符串转换为数值型态,若字符串中含有非数字的内容则会将其去除后,合并为一数字。
Weekday(date)
取的参数中的日期是一个星期的第几天,星期天为 1 、星期一为 2 、星期二为 3 依此类推。
WeekDayName(number)
依接收的参数取得星期的名称,可接收的参数为 1 7 ,星期天为 1 、星期一为 2 、星期二为 3 依此类推。
loading...
 
 
2006-3-17
ASP.NET 程序中常用的三十三种代码
  1. 打开新的窗口并传送参数:
  传送参数:
response.write(" script window.open(’*.ASPx?id="+this.DropDownList1.SelectIndex+"&id1="+...+"’) /script "
  接收参数:
string a = Request.QueryString("id";
string b = Request.QueryString("id1";
   2. 为按钮添加对话框
Button1.Attributes.Add("onclick","return confirm(’ 确认 ?’)";
button.attributes.add("onclick","if(confirm(’are you sure...?’)){return true;}else{return false;}"
   3. 删除表格选定记录
int intEmpID = (int)MyDataGrid.DataKeys[e.Item.ItemIndex];
string deleteCmd = "DELETE from Employee where emp_id = " + intEmpID.ToString()
   4. 删除表格记录警告
private void DataGrid_ItemCreated(Object sender,DataGridItemEventArgs e)
{
  switch(e.Item.ItemType)
  {
   case ListItemType.Item :
   case ListItemType.AlternatingItem :
   case ListItemType.EditItem:
    TableCell myTableCell;
    myTableCell = e.Item.Cells[14];
    LinkButton myDeleteButton ;
    myDeleteButton = (LinkButton)myTableCell.Controls[0];
    myDeleteButton.Attributes.Add("onclick","return confirm(’ 您是否确定要删除这条信息 ’);";
    break;
   default:
    break;
  }
}
   5. 点击表格行链接另一页
private void grdCustomer_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
{
  // 点击表格打开
  if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
   e.Item.Attributes.Add("onclick","window.open(’Default.aspx?id=" + e.Item.Cells[0].Text + "’);";
}
  双击表格连接到另一页
  在 itemDataBind 事件中
if(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
  string OrderItemID =e.item.cells[1].Text;
  ...
  e.item.Attributes.Add("ondblclick", "location.href=’../ShippedGrid.aspx?id=" + OrderItemID + "’";
}
  双击表格打开新一页
if(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
  string OrderItemID =e.item.cells[1].Text;
  ...
  e.item.Attributes.Add("ondblclick", "open(’../ShippedGrid.aspx?id=" + OrderItemID + "’)";
}
   特别注意:【 ?id= 处不能为 ?id =

6.
表格超连接列传递参数
ASP:HyPerlinkColumn Target="_blank" headertext="ID " DataTextField="id" NavigateUrl="aaa.aspx?id=’
 < %# DataBinder.Eval(Container.DataItem, " 数据字段 1"% ’ & name=’ %# DataBinder.Eval(Container.DataItem, " 数据字段 2"% ’ /
   7. 表格点击改变颜色
if (e.Item.ItemType == ListItemType.Item ||e.Item.ItemType == ListItemType.AlternatingItem)
{
  e.Item.Attributes.Add("onclick","this.style.backgroundColor=’#99cc00’;
    this.style.color=’buttontext’;this.style.cursor=’default’;";
  写在 DataGrid _ItemDataBound
if (e.Item.ItemType == ListItemType.Item ||e.Item.ItemType == ListItemType.AlternatingItem)
{
e.Item.Attributes.Add("onmouseover","this.style.backgroundColor=’#99cc00’;
    this.style.color=’buttontext’;this.style.cursor=’default’;";
e.Item.Attributes.Add("onmouseout","this.style.backgroundColor=’’;this.style.color=’’;";
}

   8. 关于日期格式
  日期格式设定
DataFormatString="{0:yyyy-MM-dd}"
  我觉得应该在 itembound 事件中
e.items.cell[" 你的列 "].text=DateTime.Parse(e.items.cell[" 你的列 "].text.ToString("yyyy-MM-dd")
   9. 获取错误信息并到指定页面
  不要使用 Response.Redirect, 而应该使用 Server.Transfer
   e.g
// in global.asax
protected void Application_Error(Object sender, EventArgs e) {
if (Server.GetLastError() is HttpUnhandledException)
Server.Transfer("MyErrorPage.aspx";
// 其余的非 HttpUnhandledException 异常交给 ASP.NET 自己处理就 okay
}
   Redirect 会导致 post back 的产生从而丢失了错误信息,所以页面导向应该直接在服务器端执行,这样就可以在错误处理页面得到出错信息并进行相应的处理
   10. 清空 Cookie
Cookie.Expires=[DateTime];
Response.Cookies("UserName".Expires = 0
   11. 自定义异常处理
// 自定义异常处理类
using System;
using System.Diagnostics;
namespace MyAppException
{
  /// summary
  /// 从系统异常类 ApplicationException 继承的应用程序异常处理类。
  /// 自动将异常内容记录到 Windows NT/2000 的应用程序日志
  /// /summary
  public class AppException:System.ApplicationException
  {
   public AppException()
   {
    if (ApplicationConfiguration.EventLogEnabled)LogEvent(" 出现一个未知错误。 ";
   }
  public AppException(string message)
  {
   LogEvent(message);
  }
  public AppException(string message,Exception innerException)
  {
   LogEvent(message);
   if (innerException != null)
   {
    LogEvent(innerException.Message);
   }
  }
  // 日志记录类
  using System;
  using System.Configuration;
  using System.Diagnostics;
  using System.IO;
  using System.Text;
  using System.Threading;
  namespace MyEventLog
  {
   /// summary
   /// 事件日志记录类,提供事件日志记录支持
   /// remarks
   /// 定义了 4 个日志记录方法 (error, warning, info, trace)
   /// /remarks
   /// /summary
   public class ApplicationLog
   {
    /// summary
    /// 将错误信息记录到 Win2000/NT 事件日志中
    /// param name="message" >需要记录的文本信息< /param
    /// /summary
    public static void WriteError(String message)
    {
     WriteLog(TraceLevel.Error, message);
    }
    /// summary
    /// 将警告信息记录到 Win2000/NT 事件日志中
    /// param name="message" >需要记录的文本信息< /param
    /// /summary
    public static void WriteWarning(String message)
    {
     WriteLog(TraceLevel.Warning, message);   
    }
    /// summary
    /// 将提示信息记录到 Win2000/NT 事件日志中
    /// param name="message" >需要记录的文本信息< /param
    /// /summary
    public static void WriteInfo(String message)
    {
     WriteLog(TraceLevel.Info, message);
    }
    /// summary
    /// 将跟踪信息记录到 Win2000/NT 事件日志中
    /// param name="message" >需要记录的文本信息< /param
    /// /summary
    public static void WriteTrace(String message)
    {
     WriteLog(TraceLevel.Verbose, message);
    }
    /// summary
    /// 格式化记录到事件日志的文本信息格式
    /// param name="ex" >需要格式化的异常对象< /param
    /// param name="catchInfo" >异常信息标题字符串 . /param
    /// retvalue
    /// para >格式后的异常信息字符串,包括异常内容和跟踪堆栈 . /para
    /// /retvalue
    /// /summary
    public static String FormatException(Exception ex, String catchInfo)
    {
     StringBuilder strBuilder = new StringBuilder();
     if (catchInfo != String.Empty)
     {
      strBuilder.Append(catchInfo).Append("/r/n";
     }
     strBuilder.Append(ex.Message).Append("/r/n".Append(ex.StackTrace);
     return strBuilder.ToString();
    }
    /// summary
    /// 实际事件日志写入方法
    /// param name="level" >要记录信息的级别( error,warning,info,trace). /param
    /// param name="messageText" >要记录的文本 . /param
    /// /summary
    private static void WriteLog(TraceLevel level, String messageText)
    {
     try
     {
      EventLogEntryType LogEntryType;
      switch (level)
      {
       case TraceLevel.Error:
        LogEntryType = EventLogEntryType.Error;
        break;
       case TraceLevel.Warning:
        LogEntryType = EventLogEntryType.Warning;
        break;
       case TraceLevel.Info:
        LogEntryType = EventLogEntryType.Information;
        break;
       case TraceLevel.Verbose:
        LogEntryType = EventLogEntryType.SuccessAudit;
        break;
       default:
        LogEntryType = EventLogEntryType.SuccessAudit;
        break;
      }
      EventLog eventLog = new EventLog("Application", ApplicationConfiguration.EventLogMachineName, ApplicationConfiguration.EventLogSourceName ;
      // 写入事件日志
      eventLog.WriteEntry(messageText, LogEntryType);
     }
    catch {} // 忽略任何异常
   }
  } //class ApplicationLog
}

12.Panel
横向滚动,纵向自动扩展
ASPanel style="overflow-x:scroll;overflow-y:auto;" >< /aspanel
   13. 回车转换成 Tab
script language="JavaScript" for="document" event="onkeydown"
  if(event.keyCode==13 && event.srcElement.type!=’button’ && event.srcElement.type!=’submit’ &&      event.srcElement.type!=’reset’ && event.srcElement.type!=’’&& event.srcElement.type!=’textarea’);
    event.keyCode=9;
/script
οnkeydοwn="if(event.keyCode==13) event.keyCode=9"
 
   14.DataGrid 超级连接列
DataNavigateUrlField=" 字段名 " DataNavigateUrlFormatString="http://xx/inc/delete.aspx?ID={0}" 
   15.DataGrid 行随鼠标变色
private void DGzf_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
{
  if (e.Item.ItemType!=ListItemType.Header)
  {
   e.Item.Attributes.Add( "onmouseout","this.style.backgroundColor=/""+e.Item.Style["BACKGROUND-COLOR"]+"/"";
   e.Item.Attributes.Add( "onmouseover","this.style.backgroundColor=/""+ "#EFF3F7"+"/"";
  }
}
   16. 模板列
ASP:TEMPLATECOLUMN visible="False" sortexpression="demo" headertext="ID"
ITEMTEMPLATE
ASP:LABEL text=’ %# DataBinder.Eval(Container.DataItem, "ArticleID"% ’ runat="server" width="80%" id="lblColumn" /
/ITEMTEMPLATE
/ASP:TEMPLATECOLUMN
ASP:TEMPLATECOLUMN headertext=" 选中 "
HEADERSTYLE wrap="False" horizontalalign="Center" >< /HEADERSTYLE
ITEMTEMPLATE
ASP:CHECKBOX id="chkExport" runat="server" /
/ITEMTEMPLATE
EDITITEMTEMPLATE
ASP:CHECKBOX id="chkExportON" runat="server" enabled="true" /
/EDITITEMTEMPLATE
/ASP:TEMPLATECOLUMN
  后台代码
protected void CheckAll_CheckedChanged(object sender, System.EventArgs e)
{
  // 改变列的选定,实现全选或全不选。
  CheckBox chkExport ;
  if( CheckAll.Checked)
  {
   foreach(DataGridItem oDataGridItem in MyDataGrid.Items)
   {
    chkExport = (CheckBox)oDataGridItem.FindControl("chkExport";
    chkExport.Checked = true;
   }
  }
  else
  {
   foreach(DataGridItem oDataGridItem in MyDataGrid.Items)
   {
    chkExport = (CheckBox)oDataGridItem.FindControl("chkExport";
    chkExport.Checked = false;
   }
  }
}
   17. 数字格式化
  【< %#Container.DataItem("price"% >的结果是 500.0000 ,怎样格式化为 500.00?
%#Container.DataItem("price","{0: #,##0.00}"%
int i=123456;
string s=i.ToString("###,###.00";
18. 日期格式化
  【 ASPx 页面内:< %# DataBinder.Eval(Container.DataItem,"Company_Ureg_Date"%
  显示为: 2004-8-11 19:44:28
  我只想要: 2004-8-11
%# DataBinder.Eval(Container.DataItem,"Company_Ureg_Date","{0:yyyy-M-d}"%
  应该如何改?
  【格式化日期】
  取出来 , 一般是 object((DateTime)objectFromDB).ToString("yyyy-MM-dd";
  【日期的验证表达式】
   A. 以下正确的输入格式: [2004-2-29], [2004-02-29 10:29:39 pm], [2004/12/31]
^((/d{2}(([02468][048])|([13579][26]))[/-///s]?((((0?[13578])|(1[02]))[/-///s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[/-///s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[/-///s]?((0?[1-9])|([1-2][0-9])))))|(/d{2}(([02468][1235679])|([13579][01345789]))[/-///s]?((((0?[13578])|(1[02]))[/-///s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[/-///s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[/-///s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(/s(((0?[1-9])|(1[0-2]))/[0-5][0-9])((/s)|(/[0-5][0-9])/s))([AM|PM|am|pm]{2,2})))?
   B. 以下正确的输入格式: [0001-12-31], [9999 09 30], [2002/03/03]
^/d{4}[/-///s]?((((0[13578])|(1[02]))[/-///s]?(([0-2][0-9])|(3[01])))|(((0[469])|(11))[/-///s]?(([0-2][0-9])|(30)))|(02[/-///s]?[0-2][0-9]))  
  【大小写转换】
HttpUtility.HtmlEncode(string);
HttpUtility.HtmlDecode(string)
   19. 如何设定全局变量
   Global.asax
   Application_Start() 事件中
  添加 Application[ 属性名 ] xxx;
  就是你的全局变量
   20. 怎样作到 HyPerlinkColumn 生成的连接后,点击连接,打开新窗口?
   HyperLinkColumn 有个属性 Target, 将器值设置成 "_blank" 即可 .(Target="_blank"
  【 ASPNETMENU 】点击菜单项弹出新窗口
  在你的 menuData.XML 文件的菜单项中加入 URLTarget="_blank" ,如:
?XML version="1.0" encoding="GB2312"?
MenuData ImagesBaseURL="images/"
MenuGroup
MenuItem Label=" 内参信息 " URL="Infomation.aspx"
MenuGroup ID="BBC"
MenuItem Label=" 公告信息 " URL="Infomation.aspx" URLTarget="_blank" LeftIcon="file.gif"/
MenuItem Label=" 编制信息简报 " URL="NewInfo.aspx" LeftIcon="file.gif" /
......
  最好将你的 aspnetmenu 升级到 1.2
   21. 读取 DataGrid 控件 TextBox
foreach(DataGrid dgi in yourDataGrid.Items)
{
  TextBox tb = (TextBox)dgi.FindControl("yourTextBoxId";
  tb.Text....
}
   23. DataGrid 中有 3 个模板列包含 Textbox 分别为 DG_ShuLiang ( 数量 ) DG_DanJian( 单价 ) DG_JinE( 金额 ) 分别在 5.6.7 列,要求在录入数量及单价的时候自动算出金额即 : 数量 * 单价 = 金额还要求录入时限制为 数值型 . 我如何用客户端脚本实现这个功能 ?
  〖思归〗
asp:TemplateColumn HeaderText=" 数量 "
ItemTemplate
asp:TextBox id="ShuLiang" runat=’server’ Text=’ %# DataBinder.Eval(Container.DataItem,"DG_ShuLiang"%
οnkeyup="JavaScriptoCal()"
/
asp:RegularExpressionValidator id="revS" runat="server" ControlToValidate="ShuLiang" ErrorMessage="must be integer" ValidationExpression="^/d+ " /
/ItemTemplate
/asp:TemplateColumn
asp:TemplateColumn HeaderText=" 单价 "
ItemTemplate
asp:TextBox id="DanJian" runat=’server’ Text=’ %# DataBinder.Eval(Container.DataItem,"DG_DanJian"%
οnkeyup="JavascriptoCal()"
/
asp:RegularExpressionValidator id="revS2" runat="server" ControlToValidate="DanJian" ErrorMessage="must be numeric" ValidationExpression="^/d+(/./d*)? " /
/ItemTemplate
/asp:TemplateColumn
asp:TemplateColumn HeaderText=" 金额 "
ItemTemplate
asp:TextBox id="JinE" runat=’server’ Text=’ %# DataBinder.Eval(Container.DataItem,"DG_JinE"% ’ /
/ItemTemplate
/asp:TemplateColumn >< script language="javascript"
function DoCal()
{
  var e = event.srcElement;
  var row = e.parentNode.parentNode;
  var txts = row.all.tags("INPUT";
  if (!txts.length || txts.length 3)
   return;
  var q = txts[txts.length-3].value;
  var p = txts[txts.length-2].value;
  if (isNaN(q) || isNaN(p))
   return;
  q = parseInt(q);
  p = parseFloat(p);
  txts[txts.length-1].value = (q * p).toFixed(2);
}
/script
  24.DataGrid 选定比较底下的行时,为什么总是刷新一下,然后就滚动到了最上面,刚才选定的行因屏幕的关系就看不到了。
page_load
page.smartNavigation=true
   25. Datagrid 中修改数据,当点击编辑键时,数据出现在文本框中,怎么控制文本框的大小 ?
private void DataGrid1_ItemDataBound(obj sender,DataGridItemEventArgs e)
{
  for(int i=0;i e.Item.Cells.Count-1;i++)
   if(e.Item.ItemType==ListItemType.EditType)
   {
    e.Item.Cells[i].Attributes.Add("Width", "80px"
   }
}
   26. 对话框
private static string ScriptBegin = " script language=/"JavaScript/" ";
private static string ScriptEnd = "
/script ";
public static void ConfirmMessageBox(string PageTarget,string Content)
{
  string ConfirmContent="var retValue=window.confirm(’"+Content+"’);"+"if(retValue){window.location=’"+PageTarget+"’;}";
  ConfirmContent=ScriptBegin + ConfirmContent + ScriptEnd;
  Page ParametERPage = (Page)System.Web.HttpContext.Current.Handler;
  ParameterPage.ReGISterStartupScript("confirm",ConfirmContent);
  //Response.Write(strScript);
}
   27. 将时间格式化: string aa=DateTime.Now.ToString("yyyy MM dd ";
   1.1 取当前年月日时分秒
currentTime=System.DateTime.Now;
   1.2 取当前年
int = DateTime.Now.Year;
   1.3 取当前月
int = DateTime.Now.Month; 
   1.4 取当前日
int = DateTime.Now.Day; 
   1.5 取当前时
int = DateTime.Now.Hour; 
   1.6 取当前分
int = DateTime.Now.Minute; 
   1.7 取当前秒
int = DateTime.Now.Second; 
   1.8 取当前毫秒
int 毫秒 = DateTime.Now.Millisecond; 
   28 .自定义分页代码:
  先定义变量
public static int pageCount; // 总页面数
public static int curPageIndex=1; //
当前页面 
  下一页:
if(DataGrid1.CurrentPageIndex (DataGrid1.PageCount - 1))
{
  DataGrid1.CurrentPageIndex += 1;
  curPageIndex+=1;
}
bind(); // DataGrid1 数据绑定函数 
  上一页:
if(DataGrid1.CurrentPageIndex 0)
{
  DataGrid1.CurrentPageIndex += 1;
  curPageIndex-=1;
}
bind(); // DataGrid1 数据绑定函数 
  直接页面跳转:
int a=int.Parse(JumpPage.Value.Trim());//JumpPage.Value.Trim() 为跳转值
if(a DataGrid1.PageCount)
{
  this.DataGrid1.CurrentPageIndex=a;
}
bind(); 

29
DataGrid 使用:
  添加删除确认:
private void DataGrid1_ItemCreated(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
{
  foreach(DataGridItem di in this.DataGrid1.Items)
  {
   if(di.ItemType==ListItemType.Item||di.ItemType==ListItemType.AlternatingItem)
   {
    ((LinkButton)di.Cells[8].Controls[0]).Attributes.Add("onclick","return confirm(’ 确认删除此项吗 ?’);";
   }
  }
  样式交替:
ListItemType itemType = e.Item.ItemType;
if (itemType == ListItemType.Item 
{
  e.Item.Attributes["onmouseout"] = "JavaScript:this.style.backgroundColor=’#FFFFFF’;";
  e.Item.Attributes["onmouseover"] = "Javascript:this.style.backgroundColor=’#d9ece1’;cursor=’hand’;" ;
}
else if( itemType == ListItemType.AlternatingItem)
{
  e.Item.Attributes["onmouseout"] = "javascript:this.style.backgroundColor=’#a0d7c4’;";
  e.Item.Attributes["onmouseover"] = "javascript:this.style.backgroundColor=’#d9ece1’;cursor=’hand’;" ;
  添加一个编号列:
DataTable dt= c.ExecuteRtnTableForAccess(sqltxt); // 执行 sql 返回的 DataTable
DataColumn dc=dt.Columns.Add("number",System.Type.GetType("System.String");
for(int i=0;i dt.Rows.Count;i++)
{
  dt.Rows[i]["number"]=(i+1).ToString();
}
DataGrid1.DataSource=dt;
DataGrid1.DataBind(); 
   DataGrid1 中添加一个 CheckBox ,页面中添加一个全选框
private void CheckBox2_CheckedChanged(object sender, System.EventArgs e)
{
  foreach(DataGridItem thisitem in DataGrid1.Items)
  {
   ((CheckBox)thisitem.Cells[0].Controls[1]).Checked=CheckBox2.Checked;
  }
  将当前页面中 DataGrid1 显示的数据全部删除
foreach(DataGridItem thisitem in DataGrid1.Items)
{
  if(((CheckBox)thisitem.Cells[0].Controls[1]).Checked)
  {
   string strloginid= DataGrid1.DataKeys[thisitem.ItemIndex].ToString();
   Del (strloginid); // 删除函数
  }
   30 .当文件在不同目录下,需要获取数据库连接字符串(如果连接字符串放在 Web.config ,然后在 Global.asax 中初始化)
  在 Application_Start 中添加以下代码:
Application["ConnStr"]=this.Context.Request.PhysicalApplicationPath+ConfigurationSettings.
    AppSettings["ConnStr"].ToString();
   31 变量 .ToString()
  字符型转换 转为字符串
12345.ToString("n"; // 生成 12,345.00
12345.ToString("C"; //
生成 12,345.00
12345.ToString("e"; //
生成 1.234500e+004
12345.ToString("f4"; //
生成 12345.0000
12345.ToString("x"; //
生成 3039 (16 进制 )
12345.ToString("p"; //
生成 1,234,500.00% 
   32 、变量 .Substring( 参数 1, 参数 2);
  截取字串的一部分,参数 1 为左起始位数,参数 2 为截取几位。 如: string s1 = str.Substring(0,2);
   33 .在自己的网站上登陆其他网站: ( 如果你的页面是通过嵌套方式的话,因为一个页面只能有一个 FORM ,这时可以导向另外一个页面再提交登陆信息 )
SCRIPT language="javascript"
!--
  function gook(pws)
  {
   frm.submit();
  }
//--
/SCRIPT body leftMargin="0" topMargin="0" οnlοad="javascript:gook()" marginwidth="0" marginheight="0"
form name="frm" action=" http://220.194.55.68:6080/login.PHP?retid=7259  " method="post"
tr
td
input id="f_user" type="hidden" size="1" name="f_user" runat="server"
input id="f_domain" type="hidden" size="1" name="f_domain" runat="server"
input class="box" id="f_pass" type="hidden" size="1" name="pwshow" runat="server"
INPUT id="lng" type="hidden" maxLength="20" size="1" value="5" name="lng"
INPUT id="tem" type="hidden" size="1" value="2" name="tem"
/td
/tr
/form  
  文本框的名称必须是你要登陆的网页上的名称,如果源码不行可以用 vsniffer 看看。
  下面是获取用户输入的登陆信息的代码:
string name;
name=Request.QueryString["EmailName"];
try
{
  int a=name.IndexOf("@",0,name.Length);
  f_user.Value=name.Substring(0,a);
  f_domain.Value=name.Substring(a+1,name.Length-(a+1));
  f_pass.Value=Request.QueryString["Psw"];
}
catch
{
  Script.Alert(" 错误的邮箱 !";
  Server.Transfer("index.ASPx";
}
loading...
 
 
2006-3-16
DataGrid
操作小技巧 [ ]
DataGrid 将布尔值转换为
<%# IIf(DataBinder.Eval(Container,"DataItem.sex","
"," " %>
上面是 vb 的写法 c# 的可以参照 :http://www.chinaaspx.com/comm/dotnetbbs/5/70001.htm 
改变 datagrid 中行颜色
 Private Sub dgrid_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles dgrid.ItemDataBound
            If Not e.Item.ItemIndex = -1 Then
                e.Item.Attributes.Add("onmouseover", "this.setAttribute('BKC',this.style.backgroundColor);this.style.backgroundColor='#EEEEEE'"
                e.Item.Attributes.Add("onmouseout", "this.style.backgroundColor=this.getAttribute('BKC');"
            End If
            Dim FolderID As String = Request.QueryString("FolderID"
        End Sub
删除确认 :   
   <asp:ButtonColumn Text="<div οnclick="return confirm('
确认要删除吗? ')"><img src=../../images/shared/Delete.gif></div>"      HeaderText=" 删除 " CommandName="Delete">            <HeaderStyle Wrap="False" HorizontalAlign="Center"></HeaderStyle>   <ItemStyle Wrap="False" Width="35" HorizontalAlign="Center"></ItemStyle>
   </asp:ButtonColumn>

DataGrid 新增一序号列 ......
DataGrid 新增一序号列,即类似 Excel 中的行号
添加模板列  
<Columns> 
                  <asp:TemplateColumn HeaderText="" ItemStyle-Width="50"> 
                     <ItemTemplate> 
                        <%# Container.ItemIndex+1 %> 
                     </ItemTemplate> 
                  </asp:TemplateColumn> 
</column> 

实现 datagrid 多列求和 ......
实现 datagrid 多列求和
 Sub DataGrid_DataBound(obj as object,e as DataGridItemEventArgs) 
    Dim intTotal as integer 
    Select Case e.Item.ItemType  
      Case ListItemType.Item, ListItemType.AlternatingItem 
       Dim lbl_id as label=e.item.findControl("lbl_id" 
       intTotal+=cDbl(lbl_id.text) 
      Case listItemType.footer 
       e.item.cells(0).text="
总计 :" & intTotal.tostring 
      e.item.cells(0).Attributes.add("Align","center" 
    End Select  
  End Sub  
一。其中 e.item.findControl("lbl_id" lbl_id dataGrid 中一行的一个文本框或标签;  
二。加在 DataGrid 中的 OnItemDataBound="DataGrid_DataBound" 事件中;

datagrid
中根据不同的值 ......
datagrid
中根据不同的值显示不同的颜色
Private Sub grdcheckequipment_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles grdcheckequipment.ItemDataBound 
        '
确保处理的是数据行,而不是 Header 或者 Footer  
        If e.Item.ItemType = ListItemType.Item OrElse e.Item.ItemType = ListItemType.AlternatingItem Then 
            ' 
得到 Manager 字段的值   
            Try 
                Dim isManager As DateTime = CType(DataBinder.Eval(e.Item.DataItem, "
首次接入时间 ", DateTime) 
                If isManager = "1900-01-01" Then 
                  e.Item.Cells(6).ForeColor =color.red              
End If 
            Catch 
            End Try 

        End If 
    End Sub 
 

单击 DataGrid 的行,使这 ......
单击 DataGrid 的行,使这行的数据显示在这个页面的下面,有点像 winform 的一个列表,下面一个明细 !!!^_^^_^^_^
用处:可以使一个页面显示更多的内容
*.cs 文件
 private void DataGrid1_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
  {
   if(e.Item.ItemType==ListItemType.Item||e.Item.ItemType==ListItemType.AlternatingItem)
   {
    e.Item.Attributes.Add("onmouseover","this.style['cursor']='hand'";
    e.Item.Attributes.Add("onclick","javascript
itemclick('"+e.Item.Cells[2].Text+"','"+((Label)e.Item.FindControl("lblTime").Text+"')";
   }
*.aspx 文件
function itemclick(time,obj)
 {
     document.form1.all("label1".innerText = time;
 
  document.form1.txt.value = obj; 
     }
 <DIV id="label1"   runat="server"> 统计时间 </DIV>
 <INPUT id="txt" type="text" runat="server" value=
入库时间 >
<asp:BoundColumn DataField="time1" HeaderText=" 统计时间 ">
 </asp:BoundColumn>
 <asp:TemplateColumn HeaderText="
入库时间 ">
     <ItemTemplate>
         <asp:Label ID=“lblTime” Runat=server Text='<%# DataBinder.Eval(Container.DataItem,"rukushijian"%>'>
         </asp:Label>
      </ItemTemplate>       
 </asp:TemplateColumn>

数据的绑定 DataBinder......
数据的绑定 DataBinder 
学习了一段时间 .net 后,发掘 .net 性能对于一个 application 至关重要,所以现在经常找一些可以提高性能的技巧,下面是有关 DataBinder 的一个小技巧。 
对于一般的绑定,我们使用 <%# DataBinder.Eval(Container.DataItem, " 字段名 " %> 
DataBinder.eval 绑定不必关心数据来源。不必关心数据的类型 eval 会把这个数据对象转换为一个字符串。在底层绑定做了很多工作,使用了反射性能。正因为使用方便了,但却影响了数据性能
来看下 <%# DataBinder.Eval(Container.DataItem, " 字段名 " %> 。当于 dataset 绑定时 DataItem 其实是一个 DataRowView (如果绑定的是一个数据读取器 datareader )它就是一个 IdataRecord 。)因此直接转换成 DataRowView 的话,将会给性能带来很大提升 <%# ctype(Container.DataItem,DataRowView).Row(" 字段名 " %> 对数据的绑定建议使用 <%# ctype(Container.DataItem,DataRowView).Row(" 字段名 " %> 。数据量大的时候可提高几百倍的速度。使用时注意 2 方面: 1. 需在页面添加 <%@ Import namespace="System.Data"%>.2. 注意字段名的大小写(要特别注意)。如果和查询的不一致,在某些情况下会导致比 <%# DataBinder.Eval(Container.DataItem, " 字段名 " %> 还要慢。如果想进一步提高速度,可采用 <%# ctype(Container.DataItem,DataRowView).Row(0) %> 的方法。不过其可读性不高 
loading...
 
 
2006-3-16
DataGrid
使用技巧小总结 - 个性化分页及复杂表头 [ ]
DataGrid 自定义分页导航
无需任何其他第三方控件 , DataGrid 自己分页的基础上再个性化一点 .
效果:  
DataGrid 自己的分页实现这样的效果
[1][2][3][4][5][6]   
DataGrid 自己的分页实现这样的效果
[1][2][3][4][5][6]
private void grid_ItemCreated(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
  {
   if(e.Item.ItemType==ListItemType.Pager)
   {   
    foreach (Control c in e.Item.Cells[0].Controls)
    {
     if (c is Label)  //
当前页数
     {
        Label lblpage=(Label)c;
//      lblpage.ForeColor= System.Drawing.ColorTranslator.FromHtml("#e78a29"; //#e78a29 ,#FF0000    
//      lblpage.Font.Bold=true;
        lblpage.Text="[<font color=#e78a29><b>"+lblpage.Text+"</b></font>]";    
      //((Label)c).ForeColor = System.Drawing.Color.Green;     
//      break;
     }
     if(c is LinkButton) //
链接的其他页数
     {     
         LinkButton linkButton = (LinkButton)c;      
         linkButton.Text = "[" + linkButton.Text+"]";
     }
    }   
   }
  } 

DataGrid
等控件中的自动编号:
添加一个模版列:
<asp:TemplateColumn HeaderText="No.">
    <ItemStyle HorizontalAlign="Center"></ItemStyle>
    <ItemTemplate>
        <asp:Label runat="server" Text='<%# dgCustomize.CurrentPageIndex*dgCustomize.PageSize+dgCustomize.Items.Count+1 %>'>
        </asp:Label>
    </ItemTemplate>
</asp:TemplateColumn>

DataGrid
中创建复杂表头
方法一:用 table 实现
 
  <form id="Form1" method="post" runat="server">
   <TABLE id="Table1" runat="server" cellSpacing="1" cellPadding="2" width="580" border="1"
    bgcolor="#cc6633" bordercolor="#cc9966" style="FONT-SIZE:9pt;BORDER-BOTTOM:0px">
    <TR align="center">
     <TD colspan="2" width="380" style="HEIGHT: 21px"></TD>
     <TD width="200" colspan="2" style="HEIGHT: 21px"></TD>
    </TR>
    <TR align="center">
     <TD width="200" bgcolor="#66cc99"><FONTFONT-SIZE: 9pt; COLOR: #4b4b4b; LINE-HEIGHT: 160%;">宋体
"></FONT></TD>
     <TD width="180" bgcolor="white"><FONTFONT-SIZE: 9pt; COLOR: #4b4b4b; LINE-HEIGHT: 160%;">宋体
"></FONT></TD>
     <TD width="160" bgcolor="#99cccc"></TD>
     <TD width="40" bgcolor="#009999"></TD>
    </TR>
   </TABLE>
   <aspataGrid id="DataGrid1" width="580px" AlternatingItemStyle-BackColor="#6699ff" CellPadding="2"
    CellSpacing="1" BorderWidth="1" BorderColor="#cc9966" Font-Size="9pt" runat="server" ShowHeader="False"
    AutoGenerateColumns="False">
    <Columns>
     <asp:BoundColumn DataField="Title">
      <ItemStyle Width="200px"></ItemStyle>
     </asp:BoundColumn>
     <asp:BoundColumn DataField="CreateDate">
      <ItemStyle Width="180px"></ItemStyle>
     </asp:BoundColumn>
     <asp:BoundColumn DataField="pid">
      <ItemStyle Width="160px"></ItemStyle>
     </asp:BoundColumn>
     <asp:BoundColumn DataField="HitCount">
      <ItemStyle Width="40px"></ItemStyle>
     </asp:BoundColumn>
    </Columns>
   </aspataGrid>  
  </form> 
方法二:动态生成表头
生成双层表头 :
  private void grid_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
  {
   if (e.Item.ItemType == ListItemType.Header)
   {
//    e.Item.Cells[0].ColumnSpan = 1;//
这是第一列的跨列数
    StringBuilder strtext=new StringBuilder();
    strtext.Append("//</td>";
    strtext.Append("<td colspan=4>
生活照明 </td>";
    strtext.Append("<td colspan=2>
一般照明 </td>";
    strtext.Append("<td colspan=2>
工付业 </td>";
    strtext.Append("<td colspan=2>
农业 </td>";
    strtext.Append("<td colspan=2>
合计 </td>";
    strtext.Append("</tr>";
    strtext.Append("<tr>";
    strtext.Append("<td>" + e.Item.Cells[0].Text);               
    e.Item.Cells[0].Text =strtext.ToString();
   }
}
整个表头内容: <tr><td>  e.Item.Cells[0].Text = 的内容   </td></tr>
加起来就是表头的样式。

生活照明

 
一般照明

 
工付业

 
农业

 
合计 生成三层表头 : if (e.Item.ItemType == ListItemType.Header)
   {   
    StringBuilder strtext=new StringBuilder();
    strtext.Append("</td>";
    strtext.Append("<td colspan= 6>
当月 </td>";
    strtext.Append("</tr>";

    strtext.Append("<tr>";
    strtext.Append("<td colspan=2>
居民 </td>";
    strtext.Append("<td colspan=2>
一般 </td>";
    strtext.Append("<td colspan=2>
工付业 </td>";
    strtext.Append("</tr>";

    strtext.Append("<tr>";
    strtext.Append("<td>" + e.Item.Cells[0].Text);               
    e.Item.Cells[0].Text =strtext.ToString();
   }
当月

居民

 
一般

 
工付业
loading...
 
 
2006-3-16
打造通用 ASP.NET 数据分页控件 [ ]
对于几乎所有的数据表现 Web 应用来说,组织好数据的显示方式、避免给用户带来混乱的感觉就是最主要的目标之一。每个页面显示 20 条记录当然是可以接受的,但每页显示 10000 条记录就很容易给用户带来不便了。将数据分成多个页面显示,即对数据进行分页,是解决此类问题的最常见的办法。
  一、慨述
   ASP.NET 本身只提供了一个支持数据分页的控件,即 DataGrid 分页控件,不过它比较适合 Intranet 环境使用,对于 Internet 环境来说, DataGrid 分页控件提供的功能似乎不足以构造出灵活的 Web 应用。其中一个原因是, DataGrid 控件对 Web 设计者放置分页控件的位置和分页控件的外观都有限制,例如, DataGrid 控件不允许垂直放置分页控件。另一个能够发挥分页技术优势的控件是 Repeater Web 开发者可以利用 Repeater 控件快速配置数据的显示方式,但分页功能却需要开发者自己实现。数据源在不断地变化,数据表现方式也千差万别,如果针对这些不断变动的条件分别定制分页控件,显然太浪费时间了,构造一个不限于特定表现控件的通用分页控件将极大地有利于节省时间。
  一个优秀的通用数据控件不仅提供常规的分页功能,而且还要能够:
   提供 首页 上一页 下一页 末页 分页导航按钮。
   根据数据显示情况调整自身的状态,即具有数据敏感性。如果分页控件被设置成每页显示 10 个记录,但实际上只有 9 个记录,那么分页控件不应该显示出来;在数据分成多页显示的情况下,第一个页面的 首页 上一页 按钮不应显示出来,最后一个页面的 下一页 末页 按钮也不应该显示出来。
   不能依赖于特定的数据显示控件。
   具有适应各种现有、将有数据源的能力。
   应当能够方便地配置显示方式,轻松地集成到各种应用之中。
   当分页就绪时,提醒其他控件。
   即使是缺乏经验的 Web 设计者,也要能够毫无困难地使用。
   提供有关分页信息的属性数据。
  目前市场上已经有一些提供上述功能的商业性控件,不过都价格不菲。对于许多开发者来说,自己构造一个通用的分页控件是最理想的选择。
  图一显示了本文通用分页控件的运行界面,其中用于显示的控件是一个 Repeater 控件。分页控件由两类部件构成:四个导航按钮,一组页面编号链接。
 
 

  用户可以方便地改换显示控件、改变分页控件本身的外观。例如,和分页控件协作的显示控件换成了一个 DataGrid 控件,页面编号链接和四个导航按钮分两行显示。
 

   ASP.NET 支持创建定制 Web 控件的三种方式:用户控件,复合控件,自定义控件。第三种控件即自定义控件的名称很容易引起误解。实际上,所有这三种控件都应该算是自定义控件。复合控件和微软所谓的自定义控件的不同之处在于,前者要用到 CreateChildControls() 方法, CreateChildControls() 方法允许控件根据某些事件重新绘制自身。对于本文的通用分页器,我们将使用复合控件。
  下面的 UML 序列图概括了通用分页控件的一般机制。
 

  虽然我们的目标是让通用分页控件不依赖于表现数据的控件,但很显然,总得有某种方法让分页控件访问数据。每一个从 Control 类继承的控件都提供一个 DataBinding 事件。我们把分页器本身注册成 DataBinding 事件的监听器,分页器就可以获知数据的情况并修改数据。由于所有从 Control 类继承的控件都有这个 DataBinding 事件,所以分页器控件达到了不依赖于特定数据表现控件的目标 —— 换句话说,分页器控件可以绑定到所有从 Control 类派生的控件,即它能够绑定到几乎所有的 Web 控件。
 
  二、核心功能
  当表现控件触发 DataBinding 事件,分页控件就可以获取 DataSource 属性。遗憾的是,微软没有提供所有数据绑定类实现的接口,诸如 IdataSourceProvider 之类,而且并非所有从 Control WebControl 类继承的控件都有一个 DataSource 属性,因此向上定型成 Control 类没有意义,唯一可行的办法是通过 Reflection API 直接操作 DataSoruce 属性。在讨论事件句柄方法之前,应该指出的是,为了注册事件句柄,首先必须获得一个表现控件的引用。分页控件显露了一个简单的字符串属性 BindToControl
 
public string BindToControl
{
get
{
if (_bindcontrol == null)
throw new NullReferenceException("
在使用分页控件之前,请先通过设置 BindToControl 属性绑定到一个控件。 ";
return _bindcontrol;}
set{_bindcontrol=value;}
}
  这个方法非常重要,所以最好能够抛出一个含义更明确的信息,而不是抛出标准的 NullReferenceException 异常。在分页控件的 OnInit 方法中,我们解析了对表现控件的引用。本例应当用 OnInit 事件句柄(而不是构造函数)来确保 JIT 编译的 aspx 页面已经设置了 BindToControl
protected override void OnInit(EventArgs e)
{
_boundcontrol = Parent.FindControl(BindToControl);
BoundControl.DataBinding += new EventHandler(BoundControl_DataBound);
base.OnInit(e);
...
  搜索表现控件的操作通过搜索分页控件的 Parent 控件完成,在这里, Parent 就是页面本身。按照这种方式使用 Parent 比较危险,举例来说,如果分页控件嵌入到了另一个控件之中,例如嵌入到了 Table 控件之中,则 Parent 引用实际上将是一个对 Table 控件的引用。由于 FindControl 方法只搜索当前的控件集合,除非表现控件就在该集合之中,否则不可能搜索到。一种比较安全的方法是递归地搜索各个控件集合,直至找到目标控件为止。
  找到 BoundControl 之后,我们将分页控件注册成为 DataBinding 事件的监听器。由于分页控件要操作数据源,所以该事件句柄应当是调用链中的最后一个,这一点很重要。不过,只要表现控件在 OnInit 事件句柄中注册 DataBinding 的事件句柄(默认行为),分页控件操作数据源时就不会出现问题。
   DataBound 事件句柄负责获取表现控件的 DataSource 属性。
private void BoundControl_DataBound(object sender,System.EventArgs e)
{
if (HasParentControlCalledDataBinding) return;
Type type = sender.GetType();
_datasource = type.GetProperty("DataSource";
if (_datasource == null)
throw new NotSupportedException("
分页控件要求表现控件必需包含一个 DataSource ";
object data = _datasource.GetGetMethod().Invoke(sender,null);
_builder = Adapters[data.GetType()];
if (_builder == null)
throw new NullReferenceException("
没有安装适当的适配器来处理下面的数据源类型: "+data.GetType());
_builder.Source = data;
ApplyDataSensitivityRules();
BindParent();
RaiseEvent(DataUpdate,this);
}
 
  在 DataBound 中,我们尝试通过 Reflection API 获得 DataSource 属性,然后返回实际数据源的一个引用。现在虽然已经获知了数据源,但分页控件还必须知道如何操作该数据源。为了让分页控件不依赖于特定的表现控件,问题复杂了很多。不过,如果让分页控件依赖于特定的数据源,那就背离了设计一个灵活的分页控件的目标。我们要通过一个接插式的体系结构来确保分页控件能够处理各种数据源,无论是 .NET 提供的数据源,还是自定义的数据源。
  为了提供一个健壮的、可伸缩的接插式体系结构,我们将利用 [GoF] Builder 模式构造出一个解决方案。
 
 

图四
   IDataSourceAdapter 接口定义了分页控件操作数据所需的最基本的元素,相当于 插头
 
publicinterface IDataSourceAdapter
{
int TotalCount{get;}
object GetPagedData(int start,int end);
}
   TotalCount 属性返回在处理数据之前数据源所包含元素的总数,而 GetPagedData 方法返回原始数据的一个子集,例如:假设数据源是一个包含 20 个元素的数组,分页控件将数据显示成每页 10 个元素,则第一页的元素子集是数组元素 0-9 ,第二页的元素子集是数组元素 10-19 DataViewAdapter 提供了一个 DataView 类型的插头:
internal class DataViewAdapter:IDataSourceAdapter
{
private DataView _view;
internal DataViewAdapter(DataView view)
{
_view = view;
}
public int TotalCount
{
get{return (_view == null) ? 0 : _view.Table.Rows.Count;}
}
public object GetPagedData(int start, int end)
{
DataTable table = _view.Table.Clone();
for (int i = start;i =end && i = TotalCount;i++)
{
table.ImportRow(_view[i-1].Row);
}
return table;
}
}
   DataViewAdapter 实现了 IDataSourceAdapter GetPagedData 方法,该 GetPagedData 克隆原始的 DataTable ,将原始 DataTable 中的数据导入到新的 DataTable 。该类的可见性有意地设置成 internal ,目的是为了向 Web 开发者隐藏实现细节,进而通过 Builder 类提供一个更简单的接口。
public abstract class AdapterBuilder
{
private object _source;
private void CheckForNull()
{
if (_source == null) throw new NullReferenceException("
必须提供一个合法的数据源 ";
}
public virtual object Source
{
get
{
CheckForNull();
return _source;}
set
{
_source = value;
CheckForNull();
}
}
public abstract IDataSourceAdapter Adapter{get;}
   AdapterBuilder 抽象类为 IdataSourceAdapter 类型提供了一个更容易管理的接口,由于提高了抽象程度,我们不必再直接使用 IdataSourceAdapter ,同时 AdapterBuilder 还提供了在分页数据之前执行预处理的指令。另外,该 Builder 还使得实际的实现类,例如 DataViewAdapter ,对分页控件的用户透明:
public class DataTableAdapterBuilder:AdapterBuilder
{
private DataViewAdapter _adapter;
private DataViewAdapter ViewAdapter
{
get
{
if (_adapter == null)
{
DataTable table = (DataTable)Source;
_adapter = new DataViewAdapter(table.DefaultView);
}
return _adapter;
}
}
public override IDataSourceAdapter Adapter
{
get
{
return ViewAdapter;
}
}
}
public class DataViewAdapterBuilder:AdapterBuilder
{
private DataViewAdapter _adapter;
private DataViewAdapter ViewAdapter
{
get
{ //
延迟实例化
if (_adapter == null)
{
_adapter = new DataViewAdapter((DataView)Source);
}
return _adapter;
}
}
public override IDataSourceAdapter Adapter
{
get{return ViewAdapter;}
}
}
   DataView 类型和 DataTable 类型的关系是如此密切,所以构造一个通用性的 DataAdapter 可能是有意义的,其实只要加入另一个处理 DataTable 的构造函数就足够了。遗憾的是,当用户需要不同的功能来处理某个 DataTable 时,就必须替换或继承整个类。如果我们构造一个使用同一 IdataSourceAdapter 的新 Builder ,用户在选择如何实现适配器时就拥有更多的自由。
  在分页控件中,寻找适当 Builder 类的操作由一个类型安全的集合完成。
public class AdapterCollectionictionaryBase
{
private string GetKey(Type key)
{
return key.FullName;
}
public AdapterCollection() {}
publicvoid Add(Type key,AdapterBuilder value)
{
Dictionary.Add(GetKey(key),value);
}
publicbool Contains(Type key)
{
return Dictionary.Contains(GetKey(key));
}
publicvoid Remove(Type key)
{
Dictionary.Remove(GetKey(key));
}
public AdapterBuilder this[Type key]
{
get{return (AdapterBuilder)Dictionary[GetKey(key)];}
set{Dictionary[GetKey(key)]=value;}
}
}
   AdapterCollection 依赖于 DataSource 类型, DataSource 通过 BoundControl_DataBound 巧妙地引入。这里使用的索引键是 Type.FullName 方法,确保了每一种类型索引键的唯一性,同时这也把保证每一种类型只有一个 Builder 的责任赋予了 AdapterCollection 。将 Builder 查找加入 BoundControl_DataBound 方法,结果如下:
public AdapterCollection Adapters
{
get{return _adapters;}
}
private bool HasParentControlCalledDataBinding
{
get{return _builder != null;}
}
private void BoundControl_DataBound(object sender,System.EventArgs e)
{
if (HasParentControlCalledDataBinding) return;
Type type = sender.GetType();
_datasource = type.GetProperty("DataSource";
if (_datasource == null)
throw new NotSupportedException("
分页控件要求表现控件必需包含一个 DataSource ";
object data = _datasource.GetGetMethod().Invoke(sender,null);
_builder = Adapters[data.GetType()];
if (_builder == null)
throw new NullReferenceException("
没有安装适当的适配器来处理下面的数据源类型: "+data.GetType());
_builder.Source = data;
ApplyDataSensitivityRules();
BindParent();
RaiseEvent(DataUpdate,this);
}
   BoundControl_DataBound 方法利用 HasParentControlCalledDataBinding 检查是否已经创建了 Builder ,如果是,则不再执行寻找适当 Builder 的操作。 Adapters 表的初始化在构造函数中完成:
public Pager()
{
SelectedPager=new System.Web.UI.WebControls.Style();
UnselectedPager = new System.Web.UI.WebControls.Style();
_adapters = new AdapterCollection();
_adapters.Add(typeof(DataTable),new DataTableAdapterBuilder());
_adapters.Add(typeof(DataView),new DataViewAdapterBuilder());
}
  最后一个要实现的方法是 BindParent ,用来处理和返回数据。
private void BindParent()
{
_datasource.GetSetMethod().Invoke(BoundControl,
new object[]{_builder.Adapter.GetPagedData(StartRow,ResultsToShow*CurrentPage)});
}
  这个方法很简单,因为数据处理实际上是由 Adapter 完成的。这一过程结束后,我们还要用一次 Reflection API ,不过这一次是设置表现控件的 DataSource 属性。

  三、界面设计
  至此为止,分页控件的核心功能已经差不多实现,不过如果缺少适当的表现方式,分页控件不会很有用。
  为了有效地将表现方式与程序逻辑分离,最好的办法莫过于使用模板,或者说得更具体一点,使用 Itemplate 接口。实际上,微软清楚地了解模板的强大功能,几乎每一个地方都用到了模板,甚至页面解析器本身也不例外。遗憾的是,模板并不象有些人认为的那样是一个简单的概念,需要花些时间才能真正掌握它的精髓,好在这方面的资料比较多,所以这里就不再赘述了。返回来看分页控件,它有四个按钮:首页,前一页,后一页,末页,当然另外还有各个页面的编号。四个导航按钮选自 ImageButton 类,而不是 LinkButton 类,从专业的 Web 设计角度来看,图形按钮显然要比单调的链接更有用一些。
public ImageButton FirstButton{get {return First;}}
public ImageButton LastButton{get {return Last;}}
public ImageButton PreviousButton{get {return Previous;}}
public ImageButton NextButton{get {return Next;}} 
  页面编号是动态构造的,这是因为它们依赖于数据源中记录数量的多少、每个页面显示的记录数量。页面编号将加入到一个 Panel Web 设计者可以通过 Panel 来指定要在哪里显示页面编号。有关创建页面编号的过程稍后再详细讨论,现在我们需要为分页控件提供一个模板,使得用户能够定制分页控件的外观。
[Template Container(typeof(LayoutContainer))]
public ITemplate Layout
{
get{return (_layout;}
set{_layout =value;}
}
public class LayoutContainer:Control,INamingContainer
{
public LayoutContainer()
{this.ID = "Page";}
}

   LayoutContainer 类为模板提供了一个容器。一般而言,在模板容器中加入一个定制 ID 总是不会错的,它将避免处理事件和进行页面调用时出现的问题。下面的 UML 图描述了分页控件的表现机制。
 
 

图五
  创建模板的第一步是在 aspx 页面中定义布局:
 
LAYOUT
asp:ImageButton id="First" Runat="server" imageUrl="play2L_dis.gif"
AlternateText="
首页 " >< /asp:ImageButton
asp:ImageButton id="Previous" Runat="server" imageUrl="play2L.gif"
AlternateText="
上一页 " >< /asp:ImageButton
asp:ImageButton id="Next" Runat="server" imageUrl="play2.gif"
AlternateText="
下一页 " >< /asp:ImageButton
asp:ImageButton id="Last" Runat="server" imageUrl="play2_dis.gif"
AlternateText="
末页 " >< /asp:ImageButton
asp:Panel id="Pager" Runat="server" >< /asp:Panel
/LAYOUT
  这个布局例子不包含任何格式元素,例如表格等,实际应用当然可以(而且应该)加入格式元素,请参见稍后的更多说明。
   Itemplate 接口只提供了一个方法 InstantiateIn ,它解析模板并绑定容器。
private void InstantiateTemplate()
{
_container = new LayoutContainer();
Layout.InstantiateIn(_container);
First = (ImageButton)_container.FindControl("First";
Previous = (ImageButton)_container.FindControl("Previous";
Next = (ImageButton)_container.FindControl("Next";
Last = (ImageButton)_container.FindControl("Last";
Holder = (Panel)_container.FindControl("Pager";
this.First.Click += new System.Web.UI.ImageClickEventHandler(this.First_Click);
this.Last.Click += new System.Web.UI.ImageClickEventHandler(this.Last_Click);
this.Next.Click += new System.Web.UI.ImageClickEventHandler(this.Next_Click);
this.Previous.Click += new System.Web.UI.ImageClickEventHandler(this.Previous_Click);
}
  控件的 InstatiateTemplate 方法要做的第一件事情是实例化模板,即调用 Layout.InstantiateIn(_container) 。容器其实也是一种控件,用法也和其他控件相似。 InstantiateTemplate 方法利用这一特点寻找四个导航按钮,以及用来容纳页面编号的 Panel 。导航按钮通过它们的 ID 找到,这是对分页控件的一点小小的限制:导航按钮必须有规定的 ID ,分别是 First Previous Next Last ,另外, Panel ID 必须是 Pager ,否则就会找不到。遗憾的是,就我们选定的表现机制而言,这似乎是较好的处理方式了;但可以相信的是,只要提供适当的说明文档,这一小小限制不会带来什么问题。另外一种可选择使用的办法是:让每一个按钮从 ImageButton 类继承,从而也就定义了一个新的类型;由于每一个按钮是一种不同的类型,在容器中可以实现一个递归搜索来寻找各种特定的按钮,从而不必再用到按钮的 ID 属性。
  找到四个按钮之后,再把适当的事件句柄绑定到这些按钮。在这里必须做一个重要的决定,即何时调用 InstantiateTemplate 。一般地,这类方法应当在 CreateChildControls 方法中调用,因为 CreateChildControls 方法的主要用途就是这一类创建子控件的任务。由于分页控件永远不会修改其子控件,所以它不需要 CreateChildControls 提供的功能来根据某些事件修改显示状态。显示子控件的速度总是越快越好,因此调用 InstantiateTemplate 方法的比较理想的位置是在 OnInit 事件中。
protected override void OnInit(EventArgs e)
{
_boundcontrol = Parent.FindControl(BindToControl);
BoundControl.DataBinding += new EventHandler(BoundControl_DataBound);
InstantiateTemplate();
Controls.Add(_container);
base.OnInit(e);
   OnInit 方法除了调用 InstantiateTemplate 方法,它的另一个重要任务是将容器加入分页控件。如果不将容器加入到分页器的控件集合,由于 Render 方法永远不会被调用,所以模板就不可能显示出来。
  模板还可以用编程的方式通过实现 Itemplate 接口定义,这一特性除了可作为提高灵活性的措施之外,还可以提供一个默认的模板,以便在用户没有通过 aspx 页面提供模板时使用。
public class DefaultPagerLayout:ITemplate
{
private ImageButton Next;
private ImageButton First;
private ImageButton Last;
private ImageButton Previous;
private Panel Pager;
public DefaultPagerLayout()
{
Next = new ImageButton();
First = new ImageButton();
Last = new ImageButton();
Previous = new ImageButton();
Pager = new Panel();
Next.ID="Next"; Next.AlternateText=" 下一页 ";Next.ImageUrl="play2.gif";
First.ID="First"; First.AlternateText="
首页 ";First.ImageUrl="play2L_dis.gif";
Last.ID = "Last"; Last.AlternateText ="
末页 ";Last.ImageUrl="play2_dis.gif";
Previous.ID="Previous"; Previous.AlternateText="
上一页 ";Previous.ImageUrl="play2L.gif";
Pager.ID="Pager";
}
public void InstantiateIn(Control control)
{
control.Controls.Clear();
Table table = new Table();
table.BorderWidth = Unit.Pixel(0);
table.CellSpacing= 1;
table.CellPadding =0;
TableRow row = new TableRow();
row.VerticalAlign = VerticalAlign.Top;
table.Rows.Add(row);
TableCell cell = new TableCell();
cell.HorizontalAlign = HorizontalAlign.Right;
cell.VerticalAlign = VerticalAlign.Middle;
cell.Controls.Add(First);
cell.Controls.Add(Previous);
row.Cells.Add(cell);
cell = new TableCell();
cell.HorizontalAlign= HorizontalAlign.Center;
cell.Controls.Add(Pager);
row.Cells.Add(cell);
cell = new TableCell();
cell.VerticalAlign = VerticalAlign.Middle;
cell.Controls.Add(Next);
cell.Controls.Add(Last);
row.Cells.Add(cell);
control.Controls.Add(table);
}
}
   DefaultPagerLayout 通过编程的方式提供了所有的导航元素,并将它们加入到 aspx 页面,不过这一次导航元素用标准的 HTML 表格设置了格式。现在,如果用户没有提供一个表现模板,程序将自动提供一个默认的模板。
[TemplateContainer(typeof(LayoutContainer))]
public ITemplate Layout
{
get{return (_layout == null)? new DefaultPagerLayout():_layout;}
set{_layout =value;}
}
  下面再来看看生成各个页面编号的过程。分页控件首先需要确定一些属性值,通过这些属性值来确定要生成多少不同的页面编号。
public int CurrentPage
{
get
{
string cur = (string)ViewState["CurrentPage"];
return (cur == string.Empty || cur ==null)? 1 : int.Parse(cur);
}
set
{
ViewState["CurrentPage"] = value.ToString();}
}
public int PagersToShow
{
get{return _results;}
set{_results = value;}
}
public int ResultsToShow
{
get{return _resultsperpage;}
set{_resultsperpage = value;}
}
   CurrentPage 保存的实际上是页面编号的 ViewState 中的当前页面, PagersToShow 方法定义的属性允许用户指定要显示多少页面,而 ResultsToShow 定义的属性则允许用户指定每页要显示多少记录,默认值是 10
   NumberofPagersToGenerate 返回当前应当生成的页面编号的数量。
private int PagerSequence
{
get
{
return Convert.ToInt32
(Math.Ceiling((double)CurrentPage/(double)PagersToShow));}
}
private int NumberOfPagersToGenerate
{
get{return PagerSequence*PagersToShow;}
}
private int TotalPagesToShow
{
get{return Convert.ToInt32(Math.Ceiling((double)TotalResults/(double)_resultsperpage));}
}
public int TotalResults
{
get{return _builder.Adapter.TotalCount;}
}
   TotalPagesToShow 方法返回要显示的总页面数量,由用户预设的 ResultsToShow 属性调整。

  虽然 ASP.NET 定义了一些默认的样式,不过对于分页控件的用户它们可能不是很实用。用户可以通过自定义样式来调整分页控件的外观。
public Style UnSelectedPagerStyle {get {return UnselectedPager;}}
public Style SelectedPagerStyle {get {return SelectedPager;}}
   UnSelectedPagerStyle 提供了页面编号未选中时所用的样式,而 SelectedPagerStyle 提供了页面编号被选中时所用的样式。
private void GeneratePagers(WebControl control)
{
control.Controls.Clear();
int pager = (PagerSequence-1)* PagersToShow +1;
for (;pager =NumberOfPagersToGenerate && pager =TotalPagesToShow;pager++)
{
LinkButton link = new LinkButton();
link.Text = pager.ToString();
link.ID = pager.ToString();
link.Click += new EventHandler(this.Pager_Click);
if (link.ID.Equals(CurrentPage.ToString()))
link.MergeStyle(SelectedPagerStyle);
else
link.MergeStyle(UnSelectedPagerStyle);
control.Controls.Add(link);
control.Controls.Add(new LiteralControl("&nbsp;");
}
}
private void GeneratePagers()
{
GeneratePagers(Holder);
}
 
   GeneratePagers 方法动态地创建所有页面编号,页面编号是 LinkButton 类型的按钮。各个页面编号的标签和 ID 属性通过循环赋值,同时,点击事件被绑定到适当的事件句柄。最后,页面编号被加入到一个容器控件 —— 在本例中是一个 Panel 对象。按钮 ID 起到了标识哪一个按钮触发点击事件的作用。下面是事件句柄的定义:
private void Pager_Click(object sender, System.EventArgs e)
{
LinkButton button = (LinkButton) sender;
CurrentPage = int.Parse(button.ID);
RaiseEvent(PageChanged, this,new PageChangedEventArgs(CurrentPage,PagedEventInvoker.Pager));
Update();
}
private void Next_Click(object sender, System.Web.UI.ImageClickEventArgs e)
{
if (CurrentPage
TotalPagesToShow)
CurrentPage++;
RaiseEvent(PageChanged, this,new PageChangedEventArgs(CurrentPage,PagedEventInvoker.Next));
Update();
}
private void Previous_Click(object sender, System.Web.UI.ImageClickEventArgs e)
{
if (CurrentPage
1)
CurrentPage--;
RaiseEvent(PageChanged, this,new PageChangedEventArgs(CurrentPage,PagedEventInvoker.Previous));
Update();
}
private void First_Click(object sender, System.Web.UI.ImageClickEventArgs e)
{
CurrentPage = 1;
RaiseEvent(PageChanged, this,new PageChangedEventArgs(CurrentPage,PagedEventInvoker.First));
Update();
}
private void Last_Click(object sender, System.Web.UI.ImageClickEventArgs e)
{
CurrentPage = TotalPagesToShow;
RaiseEvent(PageChanged, this,new PageChangedEventArgs(CurrentPage,PagedEventInvoker.Last));
Update();
  这些事件句柄都相似,它们首先更改分页控件的当前页面,然后刷新绑定的控件。
private void Update()
{
if (!HasParentControlCalledDataBinding) return;
ApplyDataSensitivityRules();
BindParent();
BoundControl.DataBind();
}
  首先,分页控件通过调用 HasParentControlCalledDataBinding 方法检查是否已经初始化了必要的适配器。如果是,则将前面指出的根据数据显示情况自动调整控件的规则应用到当前的控件,这些规则使得分页控件根据 BoundControl 中数据的不同情况表现出不同的行为。虽然这些规则由分页控件内部控制,但必要时可以用 [GoF] State 模式方便地移出到控件之外。
public bool IsDataSensitive
{
get{return _isdatasensitive;}
set{_isdatasensitive = value;}
}
private bool IsPagerVisible
{
get{return (TotalPagesToShow != 1) && IsDataSensitive;}
}
private bool IsPreviousVisible
{
get
{
return (!IsDataSensitive)? true:
(CurrentPage != 1);
}
}
private bool IsNextVisible
{
get
{
return (!IsDataSensitive)? true:
(CurrentPage != TotalPagesToShow);
}
}
private void ApplyDataSensitivityRules()
{
FirstButton.Visible = IsPreviousVisible;
PreviousButton.Visible = IsPreviousVisible;
LastButton.Visible = IsNextVisible;
NextButton.Visible = IsNextVisible;
if (IsPagerVisible) GeneratePagers();
}
   ApplyDataSensitivityRules 方法实施预定义的规则,诸如 IsPagerVisible IsPreviousVisible IsNextVisible 。默认情况下,分页控件将启用这些规则,但用户可以通过设置 IsDataSensitive 属性来关闭这些规则。
  至此为止,分页控件的显示部分基本设计完毕。最后剩下的结束工作是提供几个事件句柄,使得用户能够在各种分页控件事件出现时进行必要的调整。
public delegate void PageDelegate(object sender,PageChangedEventArgs e);
public enum PagedEventInvoker{Next,Previous,First,Last,Pager}
public class PageChangedEventArgs:EventArgs
{
private int newpage;
private Enum invoker;
public PageChangedEventArgs(int newpage):base()
{
this.newpage = newpage;
}
public PageChangedEventArgs(int newpage,PagedEventInvoker invoker)
{
this.newpage = newpage;
this.invoker = invoker;
}
public int NewPage {get{return newpage;}}
public Enum EventInvoker{get{return invoker;}}
}
 
  由于分页控件需要返回自定义的事件参数,所以我们定义了一个专用的 PageChangedEventArgs 类。 PageChangedEventArgs 类返回 PagedEventInvoker 类型, PagedEventInvoker 类型是可能触发事件的控件的枚举量。为了处理自定义的事件参数,我们定义了一个新的 delegate ,即 PageDelegate 。事件按照下面的形式定义:
public event PageDelegate PageChanged;
public event EventHandler DataUpdate;
  当事件没有对应的事件监听器时, ASP.NET 会抛出一个异常。分页控件定义了下列 RaiseEvent 方法。
private void RaiseEvent(EventHandler e,object sender)
{
this.RaiseEvent(e,this,null);
}
private void RaiseEvent(EventHandler e,object sender, PageChangedEventArgs args)
{
if(e!=null)
{
e(sender,args);
}
}
private void RaiseEvent(PageDelegate e,object sender)
{
this.RaiseEvent(e,this,null);
}
private void RaiseEvent(PageDelegate e,object sender, PageChangedEventArgs args)
{
if(e!=null)
{
e(sender,args);
}
}
  现在事件句柄可以通过调用各个 RaiseEvent 方法来触发事件了。
  四、应用实例
  至此为止,分页控件的设计已经全部完成,可以正式使用了。要使用该分页控件,只要把它绑定到一个表现控件即可。
asp:Repeater ID="repeater" Runat="server"
ItemTemplate
1:
%# Convert.ToString(DataBinder.Eval(Container.DataItem,"Column1")%
br
2:
%# Convert.ToString(DataBinder.Eval(Container.DataItem,"Column2")%
br
3:
%# Convert.ToString(DataBinder.Eval(Container.DataItem,"Column3")%
br
hr
/ItemTemplate
/asp:Repeater
cc1:Pager id="pager" ResultsToShow="2" runat="server" BindToControl="repeater"
SELECTEDPAGERSTYLE BackColor="Yellow" /
/cc1:Pager
  上面的 aspx 页面将分页控件绑定到一个 Repeater 控件,设置每页显示的记录数量为 2 ,选中的页面编号颜色为黄色,使用默认的布局,效果如图一。下面是另一个例子,它将分页控件绑定到一个 DataGrid ,效果如图二。
aspataGrid ID="Grid" Runat="server" >< /aspataGrid
cc1:Pager id="PagerGrid" ResultsToShow="2" runat="server" BindToControl="Grid"
SELECTEDPAGERSTYLE BackColor="Red" >< /SELECTEDPAGERSTYLE
LAYOUT
asp:ImageButton id="First" Runat="server" imageUrl="play2L_dis.gif" AlternateText=" 首页 " >< /asp:ImageButton
asp:ImageButton id="Previous" Runat="server" imageUrl="play2L.gif" AlternateText=" 上一页 " >< /asp:ImageButton
asp:ImageButton id="Next" Runat="server" imageUrl="play2.gif" AlternateText=" 下一页 " >< /asp:ImageButton
asp:ImageButton id="Last" Runat="server" imageUrl="play2_dis.gif" AlternateText=" 末页 " >< /asp:ImageButton
asp:Panel id="Pager" Runat="server" >< /asp:Panel
/LAYOUT
/cc1:Pager
  测试表明,分页控件并不依赖于特定的表现控件,它可以方便地处理不同的数据源,而且很容易使用,请读者下载本文后面的源代码参见完整的例子。
  虽然学习开发自定义 Web 控件不是一件轻松的事情,但掌握这项技能带来的好处不言而喻,只要稍微增加一些工作量,开发者就可以将普通的 Web 控件改换成多用途的通用控件,数十倍地提高工作效率,本文的分页控件只是创建通用控件来满足现有和将来表现需要的其中一个例子而已。
loading...
 
 
2006-3-13
DataGrid 中数据倒出 Excel 文件并下载 [ ]
Imports System
Imports System.Text
Namespace toExcel
' 功能:将 ASP.net DataGrid 生成 Excel 文件下载。
'Mountains
改进: 1 、支持中文 2 、隐藏列不显示
'
日期: 2002.10.30
Public Class DataGridToCSV
Public Function GenerateFile(ByRef Page As System.Web.UI.Page, ByVal MyDataGrid As System.Web.UI.WebControls.DataGrid, ByVal FileName As String) As String
Dim resp As HttpResponse
Dim colCount As Integer = MyDataGrid.Columns.Count - 1
resp = Page.Response
resp.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312" ' 解决中文乱码之关键
'resp.Charset = "utf-8"
'resp.AddFileDependency(FileName)
'resp.ContentType = "Text/HTML"
'resp.AppendHeader("Content-Type", "text/html; charset=gb2312"
resp.AppendHeader("Content-Disposition", "attachment;filename=" + FileName) ' 必要,做成下载文件

Dim colHeaders As String = ""
Dim strItems As StringBuilder = New StringBuilder()
Dim myCol As DataGridColumn
Dim i As Integer
For i = 0 To colCount
myCol = MyDataGrid.Columns(i)
If myCol.Visible = True Then
colHeaders = colHeaders & myCol.HeaderText.ToString & ","
End If
Next
If colHeaders.Length > 0 Then
colHeaders = colHeaders.Substring(0, colHeaders.LastIndexOf(",")
End If
colHeaders = colHeaders & Chr(13) & Chr(10)

resp.Write(colHeaders)
Dim colRow As String
Dim item As DataGridItem
For Each item In MyDataGrid.Items
resp.Write(FormatExportRow(colCount, item, MyDataGrid))
Next item
resp.End()
End Function
Private Function FormatExportRow(ByVal colCount As Integer, ByVal Item As DataGridItem, ByVal MyDataGrid As System.Web.UI.WebControls.DataGrid) As String
Dim strItem As String
Dim i As Integer
For i = 0 To colCount
If MyDataGrid.Columns(i).Visible = True Then
If Item.Cells(i).Text Is System.DBNull.Value Then
Item.Cells(i).Text = ""
End If
If i = colCount Then
strItem += Item.Cells(i).Text.ToString & Chr(13) & Chr(10)
Else
strItem += Item.Cells(i).Text.ToString & ","
End If
End If
Next
strItem = Replace(strItem, " ", " "
Return strItem
End Function

End Class
End Namespace

loading...
 
 
2006-3-13
ASP.net
中的 Datagrid 自定义分页功能 [ ]
这里使用的是 VB.net 语言。
DataGridPaging.aspx
 
  参考下面我的回复中,这里帖不上代码。    
 
 
DataGridPaging.aspx.vb
ImportsSystem.Data.SqlClient
ImportsSystem.Data
ImportsSystem.Web.UI
PublicClassDataGridPaging
   InheritsSystem.Web.UI.Page
   ProtectedWithEventsbtnFirstAsSystem.Web.UI.WebControls.LinkButton
   ProtectedWithEventsbtnPrevAsSystem.Web.UI.WebControls.LinkButton
   ProtectedWithEventsbtnNextAsSystem.Web.UI.WebControls.LinkButton
   ProtectedWithEventsbtnLastAsSystem.Web.UI.WebControls.LinkButton
   ProtectedWithEventslblCurrentIndexAsSystem.Web.UI.WebControls.Label
   ProtectedWithEventslblPageCountAsSystem.Web.UI.WebControls.Label
   ProtectedWithEventslblRegisterCountAsSystem.Web.UI.WebControls.Label
   ProtectedWithEventsDataGridAsSystem.Web.UI.WebControls.DataGrid
   ProtectedWithEventsDataGrid1AsSystem.Web.UI.WebControls.DataGrid
#Region"WebFormDesignerGeneratedCode"
   'ThiscallisrequiredbytheWebFormDesigner.
   <System.Diagnostics.DebuggerStepThrough()>PrivateSubInitializeComponent()
   EndSub
   PrivateSubPage_Init(ByValsenderAsSystem.Object,ByValeAsSystem.EventArgs)HandlesMyBase.Init
       'CODEGEN:ThismethodcallisrequiredbytheWebFormDesigner
       'Donotmodifyitusingthecodeeditor.
       InitializeComponent()
   EndSub
#EndRegion
   DimcnnAsNewSqlConnection("Password=; UserID=sa;InitialCatalog=northwind;DataSource=localhost;ConnectTimeout=30"
   DimadpAsNewSqlDataAdapter
   DimcmdAsNewSqlCommand
   DimdsAsNewDataSet
   '  DimintStartIndexAsLong
   ' 定义全局静态变量,记录选中页面之前的总记录数
   PrivateSharedprecedingAsLong
   PrivateSharedgridPageSizeAsInt16
   PrivateSubPage_Load(ByValsenderAsSystem.Object,ByValeAsSystem.EventArgs)HandlesMyBase.Load
       btnFirst.Text=" 最首页 "
       btnPrev.Text="
前一页 "
       btnNext.Text="
下一页 "
       btnLast.Text="
最后页 "
       IfNotIsPostBackThen
           Try
               DimcmdAsNewSqlCommand("selectcount(*)fromproducts",cnn)
               cnn.Open()
               '
设置在使用自定义分页时 DataGrid 控件中的实际项数。
               'DimiAsInt16
               'i=cmd.ExecuteScalar()
               'MyDataGrid.VirtualItemCount=(i/MyDataGrid.PageSize)
               DataGrid1.VirtualItemCount=cmd.ExecuteScalar()
           CatchexAsException
               Response.Write("<scriptlanguage=javascript>alert('
错误原因: '+exp.tostring())"
           Finally
               cnn.Close()
           EndTry
           preceding=DataGrid1.PageSize
           BindGrid()
       EndIf
   EndSub
   SubBindGrid()
       '
使用 DataSet 方法填充 DataGrid
       DimstrAsString="*"
       'DimgridPageSizeAsInt16=DataGrid1.PageSize
       gridPageSize=DataGrid1.PageSize
       DimcmdNumberAsNewSqlCommand("selectcount(*)fromproducts",cnn)
       Try
           cnn.Open()
           '
设置在使用自定义分页时 DataGrid 控件中 .VirtualItemCount 存放总的实际项数。
           DataGrid1.VirtualItemCount=cmdNumber.ExecuteScalar()
           ' 使用求余保证最后一页的合理显示
           Ifpreceding>=DataGrid1.VirtualItemCountThen
               gridPageSize=DataGrid1.VirtualItemCountModDataGrid1.PageSize
               IfgridPageSize=0Then
                   gridPageSize=DataGrid1.PageSize
               EndIf
           EndIf
           str="select"+str+"from(selecttop"&gridPageSize.ToString+str+"from(select top"+CStr(preceding)+str+"fromproductswhereproductID>0orderbyproductID)asporderbyproductIDdesc)asporderbyproductID"
           Cmd.CommandText=str
           Cmd.Connection=cnn
           adp.SelectCommand=Cmd
           'adp=NewSqlDataAdapter(str,cnn)
           adp.Fill(ds,"products"
           DataGrid1.DataSource=ds.Tables("products".DefaultView
           DataGrid1.DataBind()
       CatchexAsException
           Response.Write("
错误原因: "+ex.ToString())
           'Throwex
       Finally
           Ifcnn.State=ConnectionState.OpenThen
               cnn.Close()
           EndIf
       EndTry
       ShowStats()
       HideButton()

   EndSub
   '------------------------------------------- 下面是分页功能    -----------------------------------------------
   SubDataGrid1_Page(ByValsenderAsObject,ByValeAsDataGridPageChangedEventArgs)
       '
点击 GRID 某一页时发生
       'GridXQ.aspx
DataGrid OnPageIndexChanged="DataGrid1_Page"
       preceding=(e.NewPageIndex+1)*DataGrid1.PageSize
       DataGrid1.CurrentPageIndex=e.NewPageIndex
       BindGrid()
       ShowStats()
       HideButton()
   EndSub
   SubPagerButtonClick(ByValsenderAsObject,ByValeAsEventArgs)
       'usedbyexternalpagingUI
       ' 页面上 Grid 下方 linkbutton οnclick="PagerButtonClick"CommandArgument="next/prev/last/……"
       DimargAsString=sender.CommandArgument
       SelectCasearg
           Case"next"
               If(DataGrid1.CurrentPageIndex<=(DataGrid1.PageCount-1))Then
                   DataGrid1.CurrentPageIndex+=1
                   IfDataGrid1.CurrentPageIndex=DataGrid1.PageCount-1Then
                       preceding=DataGrid1.VirtualItemCount
                   Else
                       preceding+=gridPageSize
                   EndIf
               EndIf
           Case"prev"
               If(DataGrid1.CurrentPageIndex>0)Then
                   IfDataGrid1.CurrentPageIndex=DataGrid1.PageCount-1Then
                       preceding=(DataGrid1.PageCount-1)*DataGrid1.PageSize
                   Else
                       preceding-=gridPageSize
                   EndIf
                   DataGrid1.CurrentPageIndex-=1
               EndIf
           Case"last"
               DataGrid1.CurrentPageIndex=(DataGrid1.PageCount-1)
               preceding=DataGrid1.VirtualItemCount
           CaseElse
               'pagenumber
因为在 button.commandArgument 设置为 0
               DataGrid1.CurrentPageIndex=System.Convert.ToInt32(arg)
               preceding=DataGrid1.PageSize
       EndSelect
       If(DataGrid1.CurrentPageIndex=(DataGrid1.PageCount-1))Then
           btnNext.Enabled=False
       Else
           btnNext.Enabled=True
       EndIf
       If(DataGrid1.CurrentPageIndex=0)Then
           btnPrev.Enabled=False
       Else
           btnPrev.Enabled=True
       EndIf
       BindGrid()
       ShowStats()
       HideButton()
   EndSub
   SubShowStats()
       lblCurrentIndex.Text=" "+(DataGrid1.CurrentPageIndex+1).ToString()+" "
       lblPageCount.Text="
总共 "+DataGrid1.PageCount.ToString()+" "
       lblRegisterCount.Text="
共有 "+DataGrid1.VirtualItemCount.ToString+" 条记录 "
   EndSub
   SubHideButton()
       If(DataGrid1.CurrentPageIndex=(DataGrid1.PageCount-1))Then
           btnNext.Enabled=False
           btnLast.Enabled=False
       Else
           btnNext.Enabled=True
           btnLast.Enabled=True
       EndIf
       If(DataGrid1.CurrentPageIndex=0)Then
           btnPrev.Enabled=False
           btnFirst.Enabled=False
       Else
           btnPrev.Enabled=True
           btnFirst.Enabled=True
       EndIf
   EndSub
EndClass

loading...
 
 
2005-12-21
网页图片交换 JAVASCRIPT 代码 [ ] [ ]
clongge
17:27 PM
 
<table>
<tr>
<td align="center" valign="middle">
<script language=JavaScript>
<!--
var bannerAD=new Array();
var bannerADlink=new Array();
var adNum=0;
bannerAD[0]="11/1.jpg";
bannerADlink[0]="http://ent.qq.com/a/20050720/000018.htm"; 
bannerAD[1]="11/2.jpg";
bannerADlink[1]="http://ent.qq.com/a/20050720/000010.htm"; 
bannerAD[2]="11/3.jpg";
bannerADlink[2]="http://ent.qq.com/a/20050720/000007.htm"; 
bannerAD[3]="11/4.jpg";
bannerADlink[3]="http://ent.qq.com/a/20050720/000042.htm"; 
bannerAD[4]="11/5.jpg";
bannerADlink[4]="http://ent.qq.com/a/20050720/000042.htm"; 
bannerAD[5]="11/6.jpg";
bannerADlink[5]="http://ent.qq.com/a/20050720/000042.htm"; 
bannerAD[6]="11/7.jpg";
bannerADlink[6]="http://ent.qq.com/a/20050720/000042.htm"; 
bannerAD[7]="11/8.jpg";
bannerADlink[7]="http://ent.qq.com/a/20050720/000042.htm"; 
bannerAD[8]="11/9.jpg";
bannerADlink[8]="http://ent.qq.com/a/20050720/000042.htm"; 
bannerAD[9]="11/10.jpg";
bannerADlink[9]="http://ent.qq.com/a/20050720/000042.htm"; 
bannerAD[10]="11/11.jpg";
bannerADlink[10]="http://ent.qq.com/a/20050720/000042.htm"; 
bannerAD[11]="11/12.jpg";
bannerADlink[11]="http://ent.qq.com/a/20050720/000042.htm"; 
bannerAD[12]="11/13.jpg";
bannerADlink[12]="http://ent.qq.com/a/20050720/000042.htm"; 
function setTransition(){
if (document.all){
bannerADrotator.filters.revealTrans.Transition=Math.floor(Math.random()*23);
bannerADrotator.filters.revealTrans.apply();
}
}
function playTransition(){
if (document.all)
bannerADrotator.filters.revealTrans.play()
}
function nextAd(){
if(adNum<bannerAD.length-1)adNum++ ;
else adNum=0;
setTransition();
document.images.bannerADrotator.src=bannerAD[adNum];
playTransition();
theTimer=setTimeout("nextAd()", 4000);
}
function jump2url(){
jumpUrl=bannerADlink[adNum];
jumpTarget='_blank';
if (jumpUrl != '){
if (jumpTarget != ')window.open(jumpUrl,jumpTarget);
else location.href=jumpUrl;
}
}
function displayStatusMsg() {
status=bannerADlink[adNum];
document.returnValue = true;
}
//-->
<a onMouseOver="displayStatusMsg();return document.returnValue"
href="javascript:jump2url()" target="_self"><img
src="javascript:nextAd()"
name=bannerADrotator width=223 height=300 border=0 class="unnamed1"
style="FILTER: revealTrans(duration=2,transition=20)"></a></td>
</tr>
</table> 
 
 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值