有关注册DataItem的一些可能被忽视的事情 VS System.Web.UI.ScriptManager.RegisterStartupScript

 

UpdatePanel 对页面进行部分刷新时注册一些 Data Item ASP.NET AJAX 的特点之一。我们可以在服务器端为某个控件注册一个字符串甚至是一个对象,然后在客户端将将其取回。但是现在我希望向您展示一些您可能会忽视的事情。
  让我们先从最基本的用法开始。在一个异步回送过程中,我们可以调用 RegisterDataItem 方法将一个字符串与一个 UpdatePanel 绑定起来:
RegisterDataItem 方法调用
ScriptManager.GetCurrent( this .Page).RegisterDataItem( this .UpdatePanel1, " DataItem ");

  在客户端,如果我们监听 pageLoading pageLoaded 或者 endRequest 事件,我们就可以使用下面的代码,使用控件的 ClientID 将这个字符串取回:
将字符串取回
Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(
    function (sender, e)
    {
        var dataItem = e.get_dataItems()[" <%= this.UpdatePanel1.ClientID %> "]; // "DataItem"
        // more implementations...
    });

   RegisterDataItem 方法还有一个重载的版本会接受一个额外的参数,其作用是使用一个布尔值来表明我们注册的 dataItem 是不是已经被序列化为 JSON 。但是这里就出了一个问题 —— 甚至在官方文档中的示例也是不正确的。
  下面的代码选自官方文档中的示例:
官方文档中的示例
protected void Page_Load( object sender, EventArgs e)
{
    if (ScriptManager1.IsInAsyncPostBack)
    {
        System.Web.Script.Serialization.JavaScriptSerializer json =
            new System.Web.Script.Serialization.JavaScriptSerializer();
        ScriptManager1.RegisterDataItem(Label1, DateTime.Now.ToString());
        ScriptManager1.RegisterDataItem(Label2, json.Serialize(" more data "), true );
    }
}

  这个示例的确能够正常工作,但是它事实上掩盖了一个问题。请注意,序列化之后的 Data Item 会被 JavaScript 内置的 eval 方法解释执行:
使用 eval 函数解释执行
function Sys$WebForms$PageRequestManager$_onFormSubmitCompleted(sender, eventArgs)
{  
    //...
 
    for (i = 0; i < dataItemJsonNodes. length ; i++) {
        var dataItemJsonNode = dataItemJsonNodes[i];
        this ._dataItems[dataItemJsonNode.id] = eval(dataItemJsonNode.content) ;
    }
 
    //...
}

  在官方文档的示例中,字符串 more data 会被序列化为 "more data" (请注意多出的双引号),这样从 eval 方法中得到的结果就是 more data ,这正是我们注册的内容。这个再正常不多了,不是吗?猜猜看如果我们将一个序列化的对象注册到客户端时会发生什么事情呢?我为此写了一个示例:
注册一个对象
// the definition of Person class
public class Person
{
    public string Name;
}
 
 
// the code to register a Person object
Person person = new Person();
person.Name = " Jeffz ";
 
JavaScriptSerializer serializer = new JavaScriptSerializer();
ScriptManager.GetCurrent( this .Page).RegisterDataItem(
    this .UpdatePanel1, serializer.Serialize(person), true );

  当我们进行异步更新时就会抛出异常。似乎这是因为服务器端注册的表示 Person 对象的 JSON 字符串 {"Name":"Jeffz"} 无法被直接传递进入 eval 方法。具体的原因关乎语法方面的问题,可以在 ECMAScript Specification 中找到解释,因此我在这里就不多作解释了。那么,请注意我下面的代码:
JSON 字符串添加括号
ScriptManager.GetCurrent( this .Page).RegisterDataItem(
    this .UpdatePanel1, "(" + serializer.Serialize(person) + ")" , true );

  现在,我们的代码就能正常工作了,于是我们就可以在客户端将 Person 对象取出:
在客户段取出 Person 对象
Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(
    function (sender, e)
    {
        var person = e.get_dataItems()[" <%= this.UpdatePanel1.ClientID %> "];
        alert (person.Name); // "Jeffz"
    });

  这样看来,这个问题也就可以使用这个方法来解决了。不过为什么 ASP.NET AJAX 会使用 eval 方法,而不是定义在 Microsoft AJAX Library 中的 deserialize 方法来反序列化一个对象呢?我们可以发现,在 deserialize 方法中,一个表达式被传递给 eval 方法之前会被自动加上括号:
desrialize 方法
Sys.Serialization.JavaScriptSerializer.deserialize = function (data)
{
    try
    {   
        var exp = data.replace(...);
        return eval ('(' + exp + ')');
    }
    catch (e)
    {
         throw Error.argument('data', Sys.Res.cannotDeserializeInvalidJson);
    }
}

  我猜想,会不会是因为编写部分刷新相关代码的开发人员并不完全了解 Microsoft AJAX Library 中的功能呢?不过可能性最大的原因则是这些代码没有被完整地 Review 和测试过。事实上这并不是 ASP.NET AJAX 最终版本中唯一的 bug ,其他的还包括那个著名的 跨域名frame的拒绝访问错误 StringBuilder的Bug
  嗯,我们问题也看够了,就把目光移向别处吧。尽管逻辑上一个 Data Item 应该是一个包含信息的对象,但是请注意我们是使用 eva l 方法来 反序列化 一个 JSON 字符串的。这意味着我们事实上可以将任意的合法表达式发送到客户端,然后它就会被正确执行。请看下面的示例:
服务器端代码
ScriptManager.GetCurrent( this .Page).RegisterDataItem(
    this .UpdatePanel1, " var __f = function(){alert('Hello World!');}; __f; ", true );

客户端代码
Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(
    function (sender, e)
    {
        e.get_dataItems()[" <%= this.UpdatePanel1.ClientID %> "]();
    });

  我在上面代码中将一个函数注册为一个 Data Item 并且在客户端将其执行了。如果您深入了解 UpdatePanel 局部刷新的过程,您会注意到您在服务器端注册的 JavaScript 代码只有在页面更新结束后才会生效,也就是说,我们无法在 pageLoading 事件被触发时执行这些代码。我会在之后的文章中针对这样的设计以及如何使用 work arounds 来解决这个问题进行详细的探讨。这些 work arounds 就是基于 Data Item 注册的使用方式的,因为表示 Data Item “JSON 字符串 pageLoading 触发之前就被解释执行。
 
示例:
<% @ Page Language = " C# "  AutoEventWireup = " true "  CodeFile = " WebForm1.aspx.cs "  Inherits = " Sopu.Business.WebForm1 "   %>

<! DOCTYPE html PUBLIC  " -//W3C//DTD XHTML 1.0 Transitional//EN "   " http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd " >

< html xmlns = " http://www.w3.org/1999/xhtml "   >
< head runat = " server " >
    
< title > 无标题页 </ title >
</ head >
< body >
    
< form id = " form1 "  runat = " server " >
    
< asp:ScriptManager ID = " ScriptManager1 "  runat = " server " ></ asp:ScriptManager >  
    
< script type = " text/javascript " >
        Sys.WebForms.PageRequestManager.getInstance().add_pageLoading( 
            function(sender, e) 
            { 
            var dataItem 
=  e.get_dataItems()[ " <%= this.UpdatePanel1.ClientID %> " ]; 
            alert(dataItem.Name); 
            }); 
    
</ script >
    
< div >  
        
< asp:UpdatePanel ID = " UpdatePanel1 "  runat = " server " >  
            
< ContentTemplate >  
                
< asp:Button ID = " test "  runat = " server "  Text = " test "  OnClick = " test_Click "   />  
            
</ ContentTemplate >  
        
</ asp:UpdatePanel >  
    
</ div >  

    
</ form >
</ body >
</ html >
using  System;
using  System.Data;
using  System.Configuration;
using  System.Collections;
using  System.Web;
using  System.Web.Security;
using  System.Web.UI;
using  System.Web.UI.WebControls;
using  System.Web.UI.WebControls.WebParts;
using  System.Web.UI.HtmlControls;

using  System.Web.Script.Serialization;

namespace  Sopu.Business
{
    
public   partial   class  WebForm1 : System.Web.UI.Page
    {
        
protected   void  Page_Load( object  sender, EventArgs e)
        {

        }

        
protected   void  test_Click( object  sender, EventArgs e)
        {
            Person person 
=   new  Person();
            person.Name 
=   " Jeffz " ;

            
// System.Web.Script.Serialization.JavaScriptSerializer serializer = new JavaScriptSerializer();

            
// 方法一
            JavaScriptSerializer serializer  =   new  JavaScriptSerializer();
            ScriptManager.GetCurrent(
this .Page).RegisterDataItem( this .UpdatePanel1,  " ( "   +  serializer.Serialize(person)  +   " ) " true );

            
// 方法二
            System.Web.UI.ScriptManager.RegisterStartupScript( this .Page,  this .GetType(),  " test " " var p = ( "   +  serializer.Serialize(person)  +   " );alert(p.Name) " true );

        }


    }

    
public   class  Person
    {
        
public   string  Name;
    }



}


我为你提供订单管理的后台页面,请你重新为我生成支付页面的前后端完整代码。using System; using System.Data; using System.Data.SqlClient; using System.Web.UI; using System.Web.UI.WebControls; public partial class orders : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { // 检查用户是否登录 if (Session["user_id"] == null) { Response.Redirect("login.aspx?returnUrl=orders.aspx"); return; } BindOrders(); } } private void BindOrders() { int userId = Convert.ToInt32(Session["user_id"]); // 查询用户的所有订单 string sql = @" SELECT o.order_id, o.order_date, o.total_amount, o.payment_status, o.shipping_address FROM orders o WHERE o.user_id = @user_id ORDER BY o.order_date DESC"; SqlParameter[] parameters = { new SqlParameter("@user_id", userId) }; DataTable dtOrders = GetData(sql, parameters); if (dtOrders.Rows.Count > 0) { rptOrders.DataSource = dtOrders; rptOrders.DataBind(); } else { pnlNoOrders.Visible = true; } } protected void rptOrders_ItemDataBound(object sender, RepeaterItemEventArgs e) { if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) { // 获取当前订单ID DataRowView row = (DataRowView)e.Item.DataItem; int orderId = Convert.ToInt32(row["order_id"]); // 查询订单明细 string sql = @" SELECT oi.quantity, oi.unit_price, e.event_id, e.title, e.show_time, e.venue, e.city, e.cover_img FROM order_items oi JOIN events e ON oi.event_id = e.event_id WHERE oi.order_id = @order_id"; SqlParameter[] parameters = { new SqlParameter("@order_id", orderId) }; DataTable dtItems = GetData(sql, parameters); // 绑定订单明细 Repeater rptOrderItems = (Repeater)e.Item.FindControl("rptOrderItems"); rptOrderItems.DataSource = dtItems; rptOrderItems.DataBind(); } } protected void btnPay_Click(object sender, EventArgs e) { Button btn = (Button)sender; int orderId = Convert.ToInt32(btn.CommandArgument); // 跳转到支付页面 Response.Redirect("pay.aspx?order_id={orderId}"); } protected void btnCancel_Click(object sender, EventArgs e) { Button btn = (Button)sender; int orderId = Convert.ToInt32(btn.CommandArgument); // 取消订单逻辑 string sql = "UPDATE orders SET payment_status = 2 WHERE order_id = @order_id"; SqlParameter[] parameters = { new SqlParameter("@order_id", orderId) }; if (ExecuteNonQuery(sql, parameters) > 0) { // 重新绑定订单列表 BindOrders(); // 显示成功消息 ScriptManager.RegisterStartupScript(this, GetType(), "showalert", "alert('订单已取消');", true); } } // 获取封面图片URL public string GetCoverImage(object coverImg) { if (coverImg == DBNull.Value || string.IsNullOrEmpty(coverImg.ToString())) { return ResolveUrl("~/Pic/temp.jpg"); } string imagePath = coverImg.ToString().Trim(); if (imagePath.StartsWith("~/")) { return ResolveUrl(imagePath); } if (!imagePath.StartsWith("Pic/")) { imagePath = "Pic/" + imagePath; } if (!imagePath.StartsWith("~/")) { imagePath = "~/" + imagePath; } return ResolveUrl(imagePath); } // 获取状态CSS类 public string GetStatusCssClass(int status) { switch (status) { case 1: return "status-paid"; // 已支付 case 2: return "status-canceled"; // 已取消 default: return "status-unpaid"; // 未支付 } } // 获取状态文本 public string GetStatusText(int status) { switch (status) { case 1: return "已支付"; case 2: return "已取消"; default: return "待支付"; } } // 通用数据访问方法 private DataTable GetData(string sql, SqlParameter[] parameters = null) { string connStr = System.Configuration.ConfigurationManager.ConnectionStrings["TicketDB"].ConnectionString; using (SqlConnection conn = new SqlConnection(connStr)) { SqlCommand cmd = new SqlCommand(sql, conn); if (parameters != null) { cmd.Parameters.AddRange(parameters); } SqlDataAdapter da = new SqlDataAdapter(cmd); DataTable dt = new DataTable(); da.Fill(dt); return dt; } } // 执行非查询SQL private int ExecuteNonQuery(string sql, SqlParameter[] parameters = null) { string connStr = System.Configuration.ConfigurationManager.ConnectionStrings["TicketDB"].ConnectionString; using (SqlConnection conn = new SqlConnection(connStr)) { conn.Open(); SqlCommand cmd = new SqlCommand(sql, conn); if (parameters != null) { cmd.Parameters.AddRange(parameters); } return cmd.ExecuteNonQuery(); } } }
06-22
Imports System.Data Imports NPOI.HSSF.UserModel Imports NPOI.SS.UserModel Imports System.Collections.Generic Partial Class MIT2_AcceptQuery Inherits System.Web.UI.Page Dim db As SqlDb = New SqlDb() Dim ds As DataSet Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load If Not IsPostBack Then Dim sql = "SELECT DISTINCT 公司編號,公司名稱 FROM MITDEVIL.料號_count" ddlDataSet(pear, sql, "公司名稱", "公司編號") End If End Sub Sub ddlDataSet(ByVal dll As DropDownList, ByVal sql As String, ByVal text As String, ByVal value As String) ds = db.FillDataSet(sql) dll.Items.Clear() dll.DataSource = ds dll.DataTextField = text dll.DataValueField = value dll.DataBind() dll.Items.Insert(0, "") End Sub Protected Sub BTN_search_Click(sender As Object, e As System.EventArgs) Handles BTN_search.Click Dim sql As String = "SELECT 驗收單號 ,驗收序號 ,驗收人員 ,CONVERT(varchar(10),資料日期,111) 資料日期 ," & _ " 廠商編號 ,廠商名稱 ,料號 ,品名規格, 數量, 價格 ,單位 ,幣別 ,備註 ,廠別 ,匯率 ,異動類型 ," & _ " CONVERT(varchar(10),異動日期 ,111) 異動日期 ,集團類別 ,Price_Copy,Money,Date_Price_Copy " & _ " FROM [MITDEVIL].[計劃異動] WHERE 1=1 " If pear.Text = "" Then System.Web.UI.ScriptManager.RegisterStartupScript(UpdatePanel1, GetType(UpdatePanel), "AjaxMsgBox", "alert('請選擇基準公司!');", True) Exit Sub Else sql = sql + " AND 公司編號='" + pear.SelectedItem.Value + "'" End If If part_number.Text <> "" Then sql = sql + " AND 料號='" + part_number.Text + "'" End If If stradate.Value <> "" Then sql = sql + " AND 資料日期 >='" + stradate.Value + "'" End If If enddate.Value <> "" Then sql = sql + " AND 資料日期 <= '" + enddate.Value + "'" End If If createdate.Value <> "" Then sql = sql + " AND convert(char(10),創建日期,111) = convert(char(10),'" + createdate.Value + "',111)" End If sql = sql + " ORDER BY 資料日期 DESC " ViewState("AcceptDT") = db.FillDataSet(sql).Tables(0) GridView1.DataSource = db.FillDataSet(sql) ViewState("sql") = sql GridView1.DataBind() End Sub Protected Sub btn_export_Click(sender As Object, e As System.EventArgs) Handles btn_export.Click Dim arr As New ArrayList Try arr.Add("驗收單號") arr.Add("驗收序號") arr.Add("驗收人員") arr.Add("資料日期") arr.Add("廠商編號") arr.Add("廠商名稱") arr.Add("料號") arr.Add("品名規格") arr.Add("數量") arr.Add("價格") arr.Add("單位") arr.Add("幣別") arr.Add("備註") arr.Add("廠別") arr.Add("匯率") arr.Add("異動類型") arr.Add("異動日期") arr.Add("集團類別") arr.Add("價格冊單價") arr.Add("價格冊幣別") arr.Add("價格冊生效日期") SaveDate(CreateExcel(db.FillDataSet(ViewState("sql")), arr), "驗收單資料.xls") Catch ex As Exception Page.ClientScript.RegisterClientScriptBlock(Me.GetType(), "MsgBox", "alert(轉檔失敗,請重試或者聯繫系統負責人');", True) ' Return End Try End Sub Private Function CreateExcel(ByVal ds As DataSet, ByVal arrs As ArrayList) As NPOI.SS.UserModel.IWorkbook Dim workbook As IWorkbook = New NPOI.HSSF.UserModel.HSSFWorkbook() Dim sheet As New ArrayList Dim sheet1 As NPOI.SS.UserModel.ISheet = workbook.CreateSheet(arrs(0)) sheet.Add(sheet1) If arrs.Count = 4 Then Dim sheet4 As NPOI.SS.UserModel.ISheet = workbook.CreateSheet(arrs(3)) sheet.Add(sheet4) End If Dim headstyle As ICellStyle = workbook.CreateCellStyle Dim headfontstyle As HSSFFont = workbook.CreateFont 'Dim textfontstyle As HSSFFont = workbook.CreateFont Dim textstyle As HSSFCellStyle = workbook.CreateCellStyle Dim textstyle2 As HSSFCellStyle = workbook.CreateCellStyle Dim textstyle3 As HSSFCellStyle = workbook.CreateCellStyle Dim textstyle4 As HSSFCellStyle = workbook.CreateCellStyle Dim formact As HSSFDataFormat = workbook.CreateDataFormat Dim arr As New ArrayList With headfontstyle .Boldweight = NPOI.SS.UserModel.FontBoldWeight.Bold End With 'With textfontstyle ' .Boldweight = NPOI.SS.UserModel.FontBoldWeight.Bold ' .Color = NPOI.SS.UserModel.FontColor.Red 'End With With headstyle .Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center ' .VerticalAlignment = SS.UserModel.VerticalAlignment.Center '.WrapText = True .SetFont(headfontstyle) .BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin .BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin .BorderTop = NPOI.SS.UserModel.BorderStyle.Thin .BorderRight = NPOI.SS.UserModel.BorderStyle.Thin End With With textstyle .Alignment = NPOI.SS.UserModel.HorizontalAlignment.Left .BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin .BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin .BorderTop = NPOI.SS.UserModel.BorderStyle.Thin .BorderRight = NPOI.SS.UserModel.BorderStyle.Thin End With With textstyle2 '日期格式的 .Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center .BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin .BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin .BorderTop = NPOI.SS.UserModel.BorderStyle.Thin .BorderRight = NPOI.SS.UserModel.BorderStyle.Thin .DataFormat = HSSFDataFormat.GetBuiltinFormat("yyyy/MM/dd") End With With textstyle3 '數值帶千分位格式的 .Alignment = NPOI.SS.UserModel.HorizontalAlignment.Right .BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin .BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin .BorderTop = NPOI.SS.UserModel.BorderStyle.Thin .BorderRight = NPOI.SS.UserModel.BorderStyle.Thin '.DataFormat = HSSFDataFormat.GetBuiltinFormat("G/通用格式") .DataFormat = formact.GetFormat("0.00") End With With textstyle4 '數值格式的 .Alignment = NPOI.SS.UserModel.HorizontalAlignment.Right .BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin .BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin .BorderTop = NPOI.SS.UserModel.BorderStyle.Thin .BorderRight = NPOI.SS.UserModel.BorderStyle.Thin .DataFormat = formact.GetFormat("0") End With arr.Add(textstyle) arr.Add(textstyle2) arr.Add(textstyle3) arr.Add(textstyle4) '開始寫入SHEET1 '创建行 Dim row As NPOI.SS.UserModel.IRow = sheet(0).CreateRow(0) For k As Integer = 0 To arrs.Count - 1 '创建单元格 Dim cell As NPOI.SS.UserModel.ICell = row.CreateCell(k) '设置单元格值 cell.SetCellValue(arrs(k).ToString) cell.CellStyle = headstyle Next For i As Integer = 0 To ds.Tables(0).Rows.Count - 1 '创建行 row = sheet(0).CreateRow(i + 1) For j As Integer = 0 To ds.Tables(0).Columns.Count - 1 '创建单元格 Dim cell As NPOI.SS.UserModel.ICell = row.CreateCell(j) '设置单元格值 'cell.SetCellValue(ds.Tables(0).Rows(i)(field.Item(j).ToString).ToString) ' cell.CellStyle = textstyle SetCellValueByColumnType(row, j, ds.Tables(0).Rows(i)(j), ds.Tables(0).Columns(j), arr) Next Next For i As Integer = 0 To ds.Tables(0).Columns.Count - 1 sheet(0).AutoSizeColumn(i) Next Return workbook End Function Private Sub SetCellValueByColumnType(ByVal myExcelRow As NPOI.SS.UserModel.IRow, ByVal myNewCellIndex As Integer, _ ByVal myValue As Object, ByVal myDataColumn As DataColumn, ByVal arr As ArrayList) If myExcelRow Is Nothing Then Exit Sub If myNewCellIndex < 0 Then Exit Sub If myValue Is Nothing Then Exit Sub If myDataColumn Is Nothing Then Exit Sub Select Case (myDataColumn.DataType.ToString()) Case "System.String" '://字符串类型 myExcelRow.CreateCell(myNewCellIndex).SetCellValue(myValue.ToString().Trim) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(0) Case "System.DateTime" '://日期类型 If Not IsDBNull(myValue) Then myExcelRow.CreateCell(myNewCellIndex).SetCellValue(Convert.ToDateTime(myValue).ToShortDateString) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(1) Else myExcelRow.CreateCell(myNewCellIndex).SetCellValue(myValue.ToString().Trim) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(0) End If Case "System.Boolean" '://布尔型 If Not IsDBNull(myValue) Then If Convert.ToBoolean(myValue) Then myExcelRow.CreateCell(myNewCellIndex).SetCellValue("True") Else myExcelRow.CreateCell(myNewCellIndex).SetCellValue("False") End If End If Case "System.Int16", "System.Int32", "System.Int64" '://整型 If Not IsDBNull(myValue) Then myExcelRow.CreateCell(myNewCellIndex).SetCellValue(Convert.ToInt64(myValue)) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(3) Else myExcelRow.CreateCell(myNewCellIndex).SetCellValue(myValue.ToString().Trim) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(0) End If Case "System.Byte" If Not IsDBNull(myValue) Then myExcelRow.CreateCell(myNewCellIndex).SetCellValue(Convert.ToByte(myValue)) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(0) Else myExcelRow.CreateCell(myNewCellIndex).SetCellValue(myValue.ToString().Trim) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(0) End If Case "System.Decimal" '://浮点型 If Not IsDBNull(myValue) Then myExcelRow.CreateCell(myNewCellIndex).SetCellValue(Convert.ToDecimal(myValue)) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(2) Else myExcelRow.CreateCell(myNewCellIndex).SetCellValue(myValue.ToString().Trim) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(0) End If Case "System.Double" If Not IsDBNull(myValue) Then myExcelRow.CreateCell(myNewCellIndex).SetCellValue(Convert.ToDouble(myValue)) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(2) Else myExcelRow.CreateCell(myNewCellIndex).SetCellValue(myValue.ToString().Trim) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(0) End If Case Else myExcelRow.CreateCell(myNewCellIndex).SetCellValue(myValue.ToString().Trim) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(0) End Select End Sub Private Sub SaveDate(ByVal workbook As NPOI.SS.UserModel.IWorkbook, ByVal ExcelName As String) Dim ms As IO.MemoryStream Try '建立資料流 ms = New IO.MemoryStream() '寫入資料流 workbook.Write(ms) '在頁面輸出資料 Dim filename As String = "attachment;filename=" & HttpUtility.UrlEncode(ExcelName, Encoding.UTF8).ToString() Response.AddHeader("Content-Disposition", filename) Response.BinaryWrite(ms.ToArray()) Catch ex As Exception Finally '釋放資源 If Not ms Is Nothing Then ms.Dispose() ms.Close() End If End Try End Sub Protected Sub GridView1_PageIndexChanging(sender As Object, e As System.Web.UI.WebControls.GridViewPageEventArgs) Handles GridView1.PageIndexChanging GridView1.PageIndex = e.NewPageIndex GridView1.DataSource = ViewState("AcceptDT") GridView1.DataBind() End Sub End Cl给gridciew1绑定一个翻页功能
06-21
using System; using System.Configuration; using System.Data; using System.Data.SqlClient; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace Q4_WEB { public partial class Q4_MAIN : System.Web.UI.Page { // 数据库连接字符串 private string connectionString = ConfigurationManager.ConnectionStrings["EaPumpConnectionString"].ConnectionString; protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { // 页面首次加载时加载所有时段数据 LoadAllTimePeriods(); } } // 加载所有时段数据到Repeater控件 private void LoadAllTimePeriods() { using (SqlConnection conn = new SqlConnection(connectionString)) { string query = "SELECT dwsd, qshour, jshour FROM Eamain ORDER BY CASE dwsd WHEN '尖期' THEN 1 WHEN '峰期' THEN 2 WHEN '平期' THEN 3 WHEN '谷期' THEN 4 END, qshour"; SqlCommand cmd = new SqlCommand(query, conn); SqlDataAdapter da = new SqlDataAdapter(cmd); DataTable dt = new DataTable(); conn.Open(); da.Fill(dt); conn.Close(); // 将数据绑定到Repeater控件 rptTimePeriods.DataSource = dt; rptTimePeriods.DataBind(); } } // 在Repeater数据绑定完成后处理时间显示 protected void rptTimePeriods_ItemDataBound(object sender, RepeaterItemEventArgs e) { if (e == null) { return; } if (e.Item == null) { return; } // 只处理数据项和交替数据项 if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) { return; } // 获取当前绑定的数据项 DataRowView rowView = e.Item.DataItem as DataRowView; if (rowView == null) { return; } // 获取控件 Label lblItemPeriodType = e.Item.FindControl("lblItemPeriodType") as Label; Label lblItemStartTime = e.Item.FindControl("lblItemStartTime") as Label; Label lblItemEndTime = e.Item.FindControl("lblItemEndTime") as Label; // 检查控件是否存在 if (lblItemPeriodType == null || lblItemStartTime == null || lblItemEndTime == null) { return; } // 设置时段类型 string dwsd = rowView["dwsd"].ToString(); lblItemPeriodType.Text = dwsd; // 设置开始时间 string qshour = rowView["qshour"].ToString(); lblItemStartTime.Text = qshour; // 设置结束时间 string jshour = rowView["jshour"].ToString(); lblItemEndTime.Text = jshour; } // 添加时段按钮点击事件 protected void btnAddPeriod_Click(object sender, EventArgs e) { try { // 获取输入值 string periodType = ddlPeriodType.SelectedValue; string startHour = ddlStartHour.SelectedValue; string startMinute = ddlStartMinute.SelectedValue; string endHour = ddlEndHour.SelectedValue; string endMinute = ddlEndMinute.SelectedValue; // 组合时间格式 string startTime = $"{startHour}:{startMinute}"; string endTime = $"{endHour}:{endMinute}"; // 检查是否存在相同时间段 bool exists = false; using (SqlConnection conn = new SqlConnection(connectionString)) { string query = "SELECT COUNT(*) FROM Eamain WHERE dwsd = @dwsd AND qshour = @qshour AND jshour = @jshour"; SqlCommand cmd = new SqlCommand(query, conn); cmd.Parameters.AddWithValue("@dwsd", periodType); cmd.Parameters.AddWithValue("@qshour", startTime); cmd.Parameters.AddWithValue("@jshour", endTime); conn.Open(); int count = (int)cmd.ExecuteScalar(); conn.Close(); exists = (count > 0); } if (exists) { // 存在相同时间段,显示提示信息 ShowMessage("已添加该时段,请检查!", false); return; } // 添加新时段 using (SqlConnection conn = new SqlConnection(connectionString)) { string query = "INSERT INTO Eamain (dwsd, qshour, jshour) VALUES (@dwsd, @qshour, @jshour)"; SqlCommand cmd = new SqlCommand(query, conn); cmd.Parameters.AddWithValue("@dwsd", periodType); cmd.Parameters.AddWithValue("@qshour", startTime); cmd.Parameters.AddWithValue("@jshour", endTime); conn.Open(); int rowsAffected = cmd.ExecuteNonQuery(); conn.Close(); } // 重新加载数据 LoadAllTimePeriods(); ShowMessage("时段已成功添加!", true); } catch (Exception ex) { ShowMessage("添加失败:" + ex.Message, false); } } // 删除时段按钮点击事件 protected void btnDelete_Click(object sender, EventArgs e) { try { Button btn = (Button)sender; RepeaterItem item = (RepeaterItem)btn.NamingContainer; // 获取要删除的时段信息 Label lblItemPeriodType = (Label)item.FindControl("lblItemPeriodType"); Label lblItemStartTime = (Label)item.FindControl("lblItemStartTime"); Label lblItemEndTime = (Label)item.FindControl("lblItemEndTime"); string periodType = lblItemPeriodType.Text; string startTime = lblItemStartTime.Text; string endTime = lblItemEndTime.Text; // 删除时段 using (SqlConnection conn = new SqlConnection(connectionString)) { string query = "DELETE FROM Eamain WHERE dwsd = @dwsd AND qshour = @qshour AND jshour = @jshour"; SqlCommand cmd = new SqlCommand(query, conn); cmd.Parameters.AddWithValue("@dwsd", periodType); cmd.Parameters.AddWithValue("@qshour", startTime); cmd.Parameters.AddWithValue("@jshour", endTime); conn.Open(); cmd.ExecuteNonQuery(); conn.Close(); } // 重新加载数据 LoadAllTimePeriods(); // 构建删除成功消息 string periodTypeName = GetPeriodTypeName(periodType); ShowMessage($"已删除{periodTypeName}时段:{startTime}到{endTime}", true); } catch (Exception ex) { ShowMessage("删除失败:" + ex.Message, false); } } // 保存所有时段按钮点击事件 protected void btnSaveAll_Click(object sender, EventArgs e) { try { // 由于时段列表现在是只读显示模式,保存所有按钮不再需要执行复杂操作 // 只需显示提示信息 ShowMessage("所有时段已保存!", true); } catch (Exception ex) { ShowMessage("保存失败:" + ex.Message, false); } } // 获取时段类型中文名称 private string GetPeriodTypeName(string periodType) { switch (periodType) { case "尖期": return "尖期"; case "峰期": return "峰期"; case "平期": return "平期"; case "谷期": return "谷期"; default: return periodType; } } // 显示消息 private void ShowMessage(string message, bool isSuccess) { // 直接在客户端脚本中设置模态框内容并显示,确保消息能正确显示 string safeMessage = message.Replace("'", "\\'"); string script = $@"$(function() {{ $('#messageModal .modal-body').html('<p>{safeMessage}</p>'); $('#messageModal').modal({{ show: true, backdrop: 'static' }}); }});"; ScriptManager.RegisterStartupScript(Page, Page.GetType(), "showModal", script, true); } } }使用c#编程,为什么在删除时段信息后没有提示框
最新发布
12-09
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值