2011-09-02 125 views
1

我正在嘗試創建一個GridView,它將包含用戶和他們有權訪問的權限級別的列表。每行都有以下字段:User_ID,Username,Permission1,Permission2,...,PermissionN,其中如果用戶沒有該權限,則權限值的值爲「0」,如果他們這樣做,則爲「1」由DAL返回的列不是名爲Permission1,而是實際的權限名稱)。我想通過使用複選框來表示數據,以允許管理員一次性向大量用戶快速授予或撤銷權限。在Dynamic GridView中保留CheckBox的值TemplateField

因爲我不知道手頭的權限數量,所以我動態地創建了TemplateFields和CheckBoxes,並且這個工作正常; GridView會顯示所有用戶的當前權限級別。當我嘗試根據用戶檢查和取消選中框來更新權限時,我遇到了問題。

一旦用戶完成更改權限,我有一個「更新」按鈕,這當然會導致回發。由於回發發生在OnClick事件之前,到達OnClick時,所有複選框已被重置爲其初始值。有沒有辦法我可以在發生回發之前獲取CheckBoxes的Checked屬性的值?是否有另一種(更好)的方式來做到這一點?謝謝。

ASPX:

<asp:GridView ID="gvUsers" runat="server" AutoGenerateColumns="False" 
EnableModelValidation="True" DataKeyNames="ID"> 
</asp:GridView> 
<asp:ObjectDataSource ID="odsUsers" runat="server" SelectMethod="GET_USERS" 
TypeName="oDAL"> 
</asp:ObjectDataSource> 
<asp:Button ID="btnUpdate" runat="server" Text="Update Permissions" OnClick="btnUpdate_OnClick"/> 

代碼背後:

private static string[] excludeCols = { "ID", "Username" }; 
protected void Page_Load(object sender, EventArgs e) 
{ 
    if (!IsPostBack) // Removing the IsPostBack check refreshes the GridView when the Update button is clicked 
     bindGridViewWithHiddenID(gvUsers, ((DataView)odsUsers.Select()).Table, excludeCols); 
} 

public static bool bindGridViewWithHiddenID(GridView gv, DataTable dt, string[] excludeCols) 
{ 
    gv.Columns.Clear(); 
    gv.DataBind(); 
    if (gv != null && dt != null && dt.Rows.Count > 0) 
    { 
     DataControlField newField; 
     foreach (DataColumn column in dt.Columns) 
     { 
      if (excludeCols.Contains(column.ColumnName)) 
      { 
       newField = new BoundField(); 
       ((BoundField)newField).DataField = column.ColumnName; 
      } 
      else 
      { 
       newField = new TemplateField(); 
       ((TemplateField)newField).ItemTemplate = new CustomTemplate(column.ColumnName); 
      } 
      newField.HeaderText = column.ColumnName; 
      if (column.ColumnName == "ID" || column.ColumnName.EndsWith("_ID")) 
       newField.Visible = false; 
      gv.Columns.Add(newField); 
     } 

     gv.DataSource = dt; 
     gv.DataBind(); 
     return true; 
    } 
    return false; 

} 

// By this time execution reaches here the CheckBoxes have already been reset 
protected void btnUpdate_Click(object sender, EventArgs e) 
{ 
    ... 
} 

CustomTemplate類:

public class CustomTemplate : ITemplate 
{ 
private string binding; 
private static int count = 0; 
public CustomTemplate(string colNameBinding) 
{ 
    binding = colNameBinding; 
} 

public void InstantiateIn(Control container) 
{ 
    CheckBox chk = new CheckBox(); 
    chk.ID = "chk" + count++; 
    chk.DataBinding += new EventHandler(this.chk_OnDataBinding); 
    container.Controls.Add(chk); 
} 

public void chk_OnDataBinding(object sender, EventArgs e) 
{ 
    CheckBox chk = (CheckBox)sender; 
    GridViewRow namingContainer = (GridViewRow)chk.NamingContainer; 
    DataRowView dataRow = (DataRowView)namingContainer.DataItem; 

    if (dataRow[binding].ToString() == "1") 
     chk.Checked = true; 
    else 
     chk.Checked = false; 
} 

回答

0

這是正常現象,是正常的。它必須處理頁面生命週期和ViewState在動態添加控件上的跟蹤。我建議您閱讀Scott Mitchell的this article,特別是標題爲「視圖狀態和動態添加控件」的部分。

0

我嘗試添加GridView綁定到OnInit(),但由於CheckBoxes實際上並沒有被實例化,直到GridView是DataBound,並且由於DataBinding會將GridView恢復到它的原始狀態,我似乎又被卡住了。

相關問題