2011-09-02 2 views
1

액세스 권한이있는 사용자 및 권한 수준의 목록을 포함하는 GridView를 만들려고합니다. 각 행에는 User_ID, Username, Permission1, Permission2, ..., PermissionN과 같은 필드가 있습니다. 여기서 사용 권한 필드의 값은 사용자에게 해당 권한이 없으면 "0"이고 사용 권한이 있으면 "1"입니다. DAL에 의해 반환 된 열은 Permission1이 아니라 실제 사용 권한 이름입니다. 관리자가 신속하게 수많은 사용자에게 권한을 부여하거나 취소 할 수 있도록 CheckBox를 사용하여 데이터를 표시하려고합니다.Dynamic GridView TemplateField에서 CheckBox의 값 유지

사전 권한 수를 알 수 없으므로 동적으로 TemplateFields 및 CheckBoxes를 만들고 이것이 제대로 작동합니다. GridView는 모든 사용자의 현재 사용 권한 수준을 보여줍니다. 사용자 검사 및 확인란 선택을 기반으로 권한을 업데이트하려고하면 문제가 발생합니다.

일단 사용자가 권한 변경을 완료하면 "업데이트"버튼이있어서 물론 포스트 백이 발생합니다. 포스트 백이 OnClick 이벤트 전에 발생하기 때문에 OnClick에 도달 할 때까지 모든 CheckBox가 초기 값으로 재설정되었습니다. 포스트 백이 발생하기 전에 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()에 추가하려고 시도했지만 GridView가 DataBound가 될 때까지 CheckBoxes가 실제로 인스턴스화되지 않았기 때문에 DataBinding이 GridView를 원래 상태로 되돌릴 것이기 때문에 다시 붙어있는 것처럼 보입니다.

관련 문제