2009-12-09 3 views
1

BoundField 및 TemplateField 요소가 포함 된 GridView가 있습니다. 일부 TemplateField 요소가 동적으로 생성됩니다. 참조 용으로 GridView를 사용하고 있습니다.ASP.NET - 동적 열이있는 GridView의 문제점

<asp:GridView ID="myGridView" runat="server" AutoGenerateColumns="False" 
     DataKeyNames="ID" ShowFooter="True" EnableModelValidation="True" 
     OnLoad="myGridView_Load" OnRowCommand="myGridView_RowCommand" 
     OnRowEditing="myGridView_RowEditing" OnRowDeleting="myGridView_RowDeleting" 
     OnRowCancelingEdit="myGridView_RowCancelingEdit" 
     OnRowUpdating="myGridView_RowUpdating"> 
     <Columns> 
     <asp:BoundField DataField="Number" Visible="true" HeaderText="Test" /> 
     <asp:TemplateField HeaderText="Number"> 
      <EditItemTemplate> 
      <asp:TextBox ID="tb1" runat="server" Text='<%# Bind("Number") %>' /> 
      </EditItemTemplate> 
      <ItemTemplate> 
      <asp:Label ID="lb1" runat="server" Text='<%# Bind("Number") %>' /> 
      </ItemTemplate> 
      <FooterTemplate> 
      <asp:TextBox ID="ftb" runat="server" Text="[x]" /> 
      </FooterTemplate> 
     </asp:TemplateField> 

     <%-- Dynamically Generated Columns Will Be Inserted Here --%> 

     <asp:TemplateField HeaderText="Actions"> 
      <EditItemTemplate> 
      <asp:LinkButton ID="ulb" runat="server" Text="update" CommandName="Update" /> 
      <asp:LinkButton ID="clb" runat="server" Text="cancel" CommandName="Cancel" /> 
      </EditItemTemplate> 
      <FooterTemplate> 
      <asp:LinkButton ID="slb" runat="server" Text="insert" 
       OnClick="saveLinkButton_Click" /> 
      </FooterTemplate> 
      <ItemTemplate> 
      <asp:LinkButton ID="elb" runat="server" Text="edit" CommandName="Edit" /> 
      <asp:LinkButton ID="dlb" runat="server" Text="delete" CommandName="Delete" /> 
      </ItemTemplate> 
     </asp:TemplateField 
    </Columns>                              
     <EmptyDataTemplate> 
     <table border="0" cellpadding="0" cellspacing="0"> 
      <tr><td>Number</td></tr> 
      <tr> 
      <td><asp:TextBox ID="ntb" runat="server" /></td> 
      <td><asp:LinkButton ID="slb2" runat="server" Text="save" OnClick="saveLinkButton_Click" /></td> 
      </tr> 
     </table> 
     </EmptyDataTemplate>                     
    </asp:GridView> 

처음 GridView를로드하면 모든 것이 제대로로드됩니다. 그러나 명령 (편집, 삽입, 삭제)을 수행 할 때마다 모든 데이터가 사라집니다. 이상하게도 BoundField 값은 여전히 ​​올바르게 나타납니다. 그러나 TemplateField는 렌더링되지 않는 것 같습니다. 나는이의 GridView 작업을 사용하고 코드는 여기에 있습니다 : 동적으로 컬럼을 추가로

public partial class GridView : System.Web.UI.Page 
{ 
    private List<string> dynamicColumnNames = new List<string>(); 

    protected void Page_Load(object sender, EventArgs e) 
    { 
     LoadPageData(); 
    } 

    protected void saveLinkButton_Click(object sender, EventArgs e) 
    { 
    } 

    protected void myGridView_Load(object sender, EventArgs e) 
    { 
     if (Page.IsPostBack == false) 
     { 
      BindGridData(); 
     } 
    } 

    protected void myGridView_RowCommand(object sender, GridViewCommandEventArgs e) 
    { } 

    protected void myGridView_RowEditing(object sender, GridViewEditEventArgs e) 
    { 
     myGridView.EditIndex = e.NewEditIndex; 
     BindGridData(); 
    } 

    protected void myGridView_RowDeleting(object sender, GridViewDeleteEventArgs e) 
    { 
     LoadPageData(); 
     BindGridData(); 
    } 

    protected void myGridView_RowCancelingEdit(object sender, EventArgs e) 
    { 
     myGridView.EditIndex = -1; 
     BindGridData(); 
    } 

    protected void myGridView_RowUpdating(object sender, GridViewUpdateEventArgs e) 
    { 
     myGridView.EditIndex = -1; 
     LoadPageData(); 
     BindGridData(); 
    } 

    private void BindGridData() 
    { 
     // Create a temporary data source 
     DataTable tempData = new DataTable(); 
     tempData.Columns.Add("ID"); 
     tempData.Columns.Add("Number");   

     // Dynamically add template columns 
     foreach (string columnName in dynamicColumnNames) 
     { 
      tempData.Columns.Add(columnName); 

      TemplateField templateField = new TemplateField(); 
      templateField.HeaderTemplate = new MyTemplateField(ListItemType.Header, columnName); 
      templateField.ItemTemplate = new MyTemplateField(ListItemType.Item, columnName); 
      templateField.EditItemTemplate = new MyTemplateField(ListItemType.EditItem, columnName); 
      templateField.FooterTemplate = new MyTemplateField(ListItemType.Footer, columnName); 
      myGridView.Columns.Insert(2, templateField); 
     } 

     // Add some phony data 
     Random random = new Random(DateTime.Now.Millisecond); 
     for (int i = 0; i < 10; i++) 
     { 
      DataRow tempRow = tempData.NewRow(); 
      tempRow["Number"] = (i + 1); 

      foreach (string column in dynamicColumnNames) 
       tempRow[column] = random.NextDouble(); 
      tempData.Rows.Add(tempRow); 
     } 

     // Bind the data to the grid 
     myGridView.DataSource = tempData; 
     myGridView.DataBind(); 
    } 

    private void LoadPageData() 
    { 
     dynamicColumnNames.Add("USA"); 
     dynamicColumnNames.Add("Japan"); 
     dynamicColumnNames.Add("Mexico"); 
    } 
} 

internal class MyTemplateField : ITemplate 
{ 
    // The type of the list item 
    private ListItemType listItemType; 

    // The value to use during instantiation 
    private string value1 = string.Empty; 

    public MyTemplateField(ListItemType listItemType, string value1) 
    { 
     this.listItemType = listItemType; 
     this.value1 = value1; 
    } 

    public void InstantiateIn(Control container) 
    { 
     if (listItemType == ListItemType.Item) 
     { 
      TextBox textBox = new TextBox(); 
      textBox.ReadOnly = true; 
      textBox.DataBinding += new EventHandler(textBox_DataBinding); 
      container.Controls.Add(textBox); 
     } 
     else if (listItemType == ListItemType.EditItem) 
     { 
      TextBox textBox = new TextBox(); 
      textBox.DataBinding += new EventHandler(textBox_DataBinding); 
      container.Controls.Add(textBox); 
     } 
     else if (listItemType == ListItemType.Header) 
     { 
      Literal literal = new Literal(); 
      literal.Text = value1; 
      container.Controls.Add(literal); 
     } 
     else if (listItemType == ListItemType.Footer) 
     { 
      TextBox textBox = new TextBox(); 
      container.Controls.Add(textBox); 
     } 
    } 

    private void textBox_DataBinding(object sender, EventArgs e) 
    { 
     TextBox textBox = (TextBox)(sender); 
     GridViewRow row = (GridViewRow)(textBox.NamingContainer); 

     textBox.Text = DataBinder.Eval(row.DataItem, value1).ToString(); 
    } 
} 

는 어떻게의 GridView에서 명령을 사용합니까? 내 코드에 어떤 문제가 있습니까?

감사합니다.

답변

0

동적으로 추가 된 컨트롤을 각 게시물에 추가해야하며 첫 페이지로드시 이러한 컨트롤을 추가 할 수 없습니다. Page.IsPostBack == false에서 BindGridData()을 삭제 해보세요.

+0

나는 똑같은 생각. 불행히도, 그것은 단지 ListItemType.Item 절이 실행되도록합니다. 그러나 ListItemType.EditItem 절은 실행되지 않습니다. 이 때문에이 제안 된 솔루션은 문제를 해결하지 못합니다. 댓글을 주셔서 감사합니다. – user208662

+0

Gridview에서 템플릿 열을 동적으로 채우는 더 좋은 방법이 있습니까? – venkat

관련 문제