ASP.NET DataGrid为空

时间:2015-06-13 13:14:09

标签: c# asp.net data-binding datagrid

我有一个ASP.NET数据网格,它位于用户控件上。我有一个主页面,它添加了用户控件(有时是用户控件的多个副本),并在发回邮件时恢复它们。

dataGrid具有插入/编辑/删除链接。我可以将多个用户控件副本添加到页面中,插入/编辑删除功能可以完美地用于每个单独的控件。

昨天我使用Text ='<%#DocumentTitle%>'格式向主页添加了一些与用户控件无关的属性绑定。最初,在添加Page.DataBind()之前,我无法使用它。到主页面的Page_Load方法。此时属性绑定开始正常工作,但后来我注意到插入功能已停止在每个用户控件内的datagrid中工作....我调试并发现当下一行执行时,它会在控件内找到文本字段dataGrid为空或"":

eInfo.Ref = ((TextBox)gvEG.FooterRow.FindControl("txtEmployeeName")).Text;

如果从主页面中删除page.DataBind()方法,则属性绑定将停止工作,但userControl中的dataGrid将开始工作。

我的问题有两个问题i)为什么看似无关的变化会影响dataGrid,以及ii)我该怎样做才能让这个变得有效?

我已在下面添加了我的代码的相关部分......或者至少我认为是相关部分。

Default.aspx的

    <div class="general">        
    <asp:TextBox Width="488" runat="server" placeholder="Document Title"  Text='<%# DocumentTitle %>'></asp:TextBox>
    </div>

Default.aspx.cs

protected void Page_Load(object sender, EventArgs e)
    {           
        if (!IsPostBack)
        {
            // Create an empty user control for the first requirements section.
            EmployeeSectionUserControl myUserControl1 = (EmployeeSectionUserControl )LoadControl("~/EmployeeSectionUserControl .ascx");


            // Add it to the panel control holding all the user controls.
            MainPanel.Controls.Add(myUserControl1);

            DocumentTitle = "I am the default document title and I'm bound.";
        }
        else
        {
            // Do nothing
        }            
        Page.DataBind();
    }

EmployeeSectionUserControl.ascx

<asp:GridView ID="gvEG" runat="server" AutoGenerateColumns="False" CssClass="grid"
AlternatingRowStyle-CssClass="gridAltRow" RowStyle-CssClass="gridRow" ShowFooter="True"
EditRowStyle-CssClass="gridEditRow" FooterStyle-CssClass="gridFooterRow" OnRowCancelingEdit="gvEG_RowCancelingEdit"
OnRowCommand="gvEG_RowCommand" OnRowDataBound="gvEG_RowDataBound" OnRowDeleting="gvEG_RowDeleting"
OnRowEditing="gvEG_RowEditing" OnRowUpdating="gvEG_RowUpdating" DataKeyNames="Id" ShowHeaderWhenEmpty="true">
<Columns>
    <asp:TemplateField HeaderText="Id" HeaderStyle-HorizontalAlign="Left" ControlStyle-Width="50px">
        <ItemTemplate>
            <%# Eval("Id")%>
        </ItemTemplate>
    </asp:TemplateField>

    <asp:TemplateField HeaderText="Ref" HeaderStyle-HorizontalAlign="Left" ControlStyle-Width="90px">
        <EditItemTemplate>
            <asp:TextBox ID="txtEmployeeName" runat="server" Text='<%# Bind("Ref") %>'
                Width="90px"></asp:TextBox>                
        </EditItemTemplate>
        <FooterTemplate>
            <asp:TextBox ID="txtEmployeeName" runat="server" Width="90px"></asp:TextBox>                
        </FooterTemplate>

EmployeeSectionUserControl.ascx.cs

protected void gvEG_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        if (e.CommandName.Equals("Insert"))
        {
            employeeInfo eInfo = new employeeInfo();
            eInfo.Id = 999;// Convert.ToInt32(((TextBox)gvEG.FooterRow.FindControl("Id")).Text);

            // If we're inserting from the EmptyDataTemplate( ie an empty table ) of the gridview then we need to retreive the data differently.
            // So we perform a check on the gridView FooterRow and if it's null then we can assume it's an empty table.
            if (gvEG.FooterRow == null)
            {
                TextBox referenceTxtBox = (((Control)e.CommandSource).NamingContainer).FindControl("txtEmployeeName") as TextBox;
                eInfo.Ref = referenceTxtBox.Text;                    
            }
            else
            {                    
                eInfo.Ref = ((TextBox)gvEG.FooterRow.FindControl("txtEmployeeName")).Text;
                eInfo.Need = 
            }

            // Store Update and Re-bind data to grid.
        }           
    }

1 个答案:

答案 0 :(得分:0)

Page.DataBind()在它的子节点上调用DataBind,因此它会在文本框中更新DocumentTitle,但它也会对你的网格进行数据绑定。我没有在你的网格中看到一个DataSource集,就像EntityDataSource一样,所以我假设你在代码中自己进行数据的智能检索(和准备)并自己设置DataSource:

gvEg.DataSource = someCollection;
gvEg.DataBind();

在get上加载用户控件并且可能通过指定DataSource来调用此DataBind。它绑定然后你调用Page.DataBind(),它可能也触发另一个DataBind for gvEg但是因为DataSource设置它显示相同。

在帖子后面,你不应该在处理事件之前做一个DataBind()。您对Page.DataBind()的调用就是这样做的。它触发没有DataSource的DataBind()。然后rowCommand来检查页脚中的TextBox,由于没有元素的DataBind,它被清除。

你应该做的是: 你不应该使用Page.DataBind()。如果你这样做,你需要在所有数据源设置正确的时刻,并且在回发期间不应该踢它。一般来说,我不建议使用它,因为它使它更复杂,如果你没有正确设置你的应用程序,它可能只是帮助一点。 在你的情况下,它绝对没有必要。您的textBox是一个服务器控件,它不属于任何绑定(GridView,Repeater,ListView)。因此,您的textBox会立即显示在您的代码中。 所以你应该:

  1. 为textBox提供一个可以使用的ID,如txtDocumentTitle

     <asp:TextBox Width="488" ID="txtDocumentTitle" runat="server" placeholder="Document Title"></asp:TextBox>
    
  2. 使用以下命令替换设置DocumentTitle(除非您需要其它内容):

     txtDocumentTitle.Text = "I am the default document title and I'm bound.";
    
  3. 删除Page.DataBind();

  4. 因此,访问服务器控件可以立即访问,因为它们也是页面或控件中的属性。