2012-06-29 31 views
2

這個問題看起來很簡單,但我找不到答案。我相信我錯過了一些東西。如何在ASP.NET WebForms中處理來自數據綁定控件的命令?

我想用一個數據綁定控件(比如一個ListView)和一個控件在項目模板中做一個回發(一個Button)。我希望按鈕對這個項目中的數據執行一些操作。

的代碼看起來是這樣的:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebFormListCommand.aspx.cs" 
    Inherits="TestWebApplication.WebFormListCommand" %> 

<!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"> 
    <div> 
     <asp:ListView ID="lvTest" runat="server" EnableViewState="false" 
      onitemdatabound="lvTest_ItemDataBound" onitemcommand="lvTest_ItemCommand"> 
      <ItemTemplate> 
       <br /> 
       <asp:Button ID="btnTest" runat="server" /> 
      </ItemTemplate> 
     </asp:ListView> 
    </div> 
    </form> 
</body> 
</html> 

後面的代碼:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

namespace TestWebApplication 
{ 
    public partial class WebFormListCommand : System.Web.UI.Page 
    { 
     protected void Page_Init(object sender, EventArgs e) 
     { 
      if (!IsPostBack) 
      { 
       lvTest.DataSource = Enumerable.Range(0, 5); 
       lvTest.DataBind(); 
      } 
      else 
      { 
       lvTest.DataSource = Enumerable.Range(5, 5); 
       lvTest.DataBind(); 
      } 
     } 
     protected void Page_Load(object sender, EventArgs e) 
     { 

     } 

     protected void lvTest_ItemDataBound(object sender, ListViewItemEventArgs e) 
     { 
      Button button = (Button)e.Item.FindControl("btnTest"); 
      int value = (int)e.Item.DataItem; 
      button.CommandName = "someCommand"; 
      button.CommandArgument = value.ToString(); 
      button.Text = value.ToString(); 
     } 


     protected void lvTest_ItemCommand(object sender, ListViewCommandEventArgs e) 
     { 
      //e.CommandArgument has the new value from the new databinding 
     } 

    } 
} 

的問題是,當按下按鈕e.CommandArgument已經從回傳數據綁定的值。如果我不回發數據綁定,那麼事件根本就不會發生。在大多數情況下,這不是問題,因爲您可以綁定到相同的數據。但是,如果一個用戶刪除了例如項目3,並且第二個用戶決定在同一時間刪除項目3,則第二個用戶將實際刪除第四個項目,因爲這些項目將在回發時重新排序。如果啓用了ViewState,則可以避免這種情況,但應該可以在不使用ViewState的情況下執行命令(應避免使用ViewState的所有位置都是數據綁定控件)。爲了增加傷害,我可以清楚地看到原始(正確)值被髮布到服務器。它可以通過Request.Form [「lvTest $ ctrl2 $ btnTest」](關鍵是觸發回發的實際控件的UniqueID)檢索到

我已經嘗試了很多方法將命令應用於正確的項目使用按鈕單擊而不是項目命令,使用DataKeys等,但我無法得到正確的數據項返回值。看起來數據綁定控件總是使用行號來獲取命令參數,而不是瀏覽器實際發佈的值。我發現的唯一方法是手動查看Request.Form集合,但這看起來不正確。當然,我可以通過連接JavaScript函數和AJAX調用來解決問題,但我想知道如何以純WebForms方式解決此問題。我錯過了什麼?從Page_Init

回答

1
  1. 移動代碼插入的Page_Load

  2. 註釋掉

    lvTest.DataSource = Enumerable.Range(5,5);

    lvTest.DataBind();

然後看看它是否有效。

我還設置CommandName聲明並綁定ComanndArgument屬性,而不是把它放在lvTest_ItemDataBound

UPDATE:

  1. 不要回傳
  2. 啓用視圖狀態重新綁定您ListView

標記:

<div> 
    <asp:ListView ID="lvTest" runat="server" 
     onitemdatabound="lvTest_ItemDataBound" onitemcommand="lvTest_ItemCommand"> 
     <ItemTemplate> 
      <br /> 
      <asp:Button ID="btnTest" runat="server" /> 
     </ItemTemplate> 
    </asp:ListView> 
</div> 
<asp:Label Text="" ID="lblMessage" runat="server" /> 

C#

protected void Page_Init(object sender, EventArgs e) 
    { 
     if (!IsPostBack) 
     { 
      lvTest.DataSource = Enumerable.Range(0, 5); 
      lvTest.DataBind(); 
     } 
     else 
     { 
      //lvTest.DataSource = Enumerable.Range(5, 5); 
      //lvTest.DataBind(); 
     } 
    } 
    protected void Page_Load(object sender, EventArgs e) 
    { 

    } 

    protected void lvTest_ItemDataBound(object sender, ListViewItemEventArgs e) 
    { 
     Button button = (Button)e.Item.FindControl("btnTest"); 
     int value = (int)e.Item.DataItem; 
     button.CommandName = "someCommand"; 
     button.CommandArgument = value.ToString(); 
     button.Text = value.ToString(); 
    } 


    protected void lvTest_ItemCommand(object sender, ListViewCommandEventArgs e) 
    { 
     //e.CommandArgument has the new value from the new databinding 
     lblMessage.Text = e.CommandArgument.ToString(); 
    } 
+0

如果我註釋掉的回傳數據綁定和禁用ViewState中點擊事件不復活。我在後面的代碼中進行數據綁定,因爲在ASP.NET 4.5之前,沒有辦法使用靜態類型聲明性數據綁定,即通過Eval/Bind的聲明性數據綁定是邪惡的。然而,聲明式數據綁定在這種情況下並沒有任何區別。 – Stilgar

+0

@Stilgar複製/粘貼代碼,它的工作原理 –

+0

它的工作原理是因爲您的ListView控件沒有禁用其ViewState。正如問題中所述,如果啓用ViewState,一切正常,但不知何故,我不想讓ListView和Grids啓用ViewState,因爲這正是應禁用它以防止增大頁面大小的地方。 – Stilgar

相關問題