GridView RowUpdating期间缺少动态添加的控件

时间:2012-02-06 21:05:16

标签: c# asp.net gridview

我有一个带有TemplateField列的GridView,我将PlaceHolder控件放入其中。在GridView的DataBound事件中,我动态地向PlaceHolder添加一些CheckBox。这很好,并按预期显示。

我的问题是在RowUpdating事件期间,PlaceHolder不包含任何控件;我的CheckBoxes丢失了。我还注意到它们在RowEditing事件中丢失了。

我希望能够在RowUpdating事件期间获取CheckBoxes的值,以便将它们保存到数据库中。

这是一些示例代码。我已经减少了很多以减小尺寸,但如果你想看到具体细节,我会很乐意添加更多。

HTML:

<asp:GridView ID="gridView" runat="server" AutoGenerateColumns="False" 
    ondatabound="gridView_DataBound" onrowupdating="gridView_RowUpdating" 
    onrowediting="gridView_RowEditing" DataKeyNames="ID">
    <Columns>
        <asp:TemplateField HeaderText="Countries">
            <ItemTemplate>
                <asp:PlaceHolder ID="countriesPlaceHolder" runat="server"></asp:PlaceHolder>
            </ItemTemplate>
            <EditItemTemplate>
                <asp:PlaceHolder ID="countriesPlaceHolder" runat="server"></asp:PlaceHolder>
            </EditItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField ShowHeader="False">
            <ItemTemplate>
                <asp:LinkButton ID="editButton" runat="server" CommandName="Edit" Text="Edit"></asp:LinkButton>
            </ItemTemplate>
            <EditItemTemplate>
                <asp:LinkButton ID="updateButton" runat="server" CommandName="Update" Text="Update"></asp:LinkButton>
            </EditItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

代码背后:

// This method works fine, no obvious problems here.
protected void gridView_DataBound(object sender, EventArgs e)
{
    // Loop through the Holidays that are bound to the GridView
    var holidays = (IEnumerable<Holiday>)gridView.DataSource;
    for (int i = 0; i < holidays.Count(); i++)
    {
        // Get the row the Holiday is bound to
        GridViewRow row = gridView.Rows[i];
        // Get the PlaceHolder control
        var placeHolder = (PlaceHolder)row.FindControl("countriesPlaceHolder");
        // Create a CheckBox for each country and add it to the PlaceHolder
        foreach (Country country in this.Countries)
        {
            bool isChecked = holidays.ElementAt(i).Countries.Any(item => item.ID == country.ID);
            var countryCheckBox = new CheckBox
            {
                Checked = isChecked,
                ID = country.Abbreviation + "CheckBox",
                Text = country.Abbreviation
            };
            placeHolder.Controls.Add(countryCheckBox);
        }
    }
}

protected void gridView_RowEditing(object sender, GridViewEditEventArgs e)
{
    // EXAMPLE: I'm expecting checkBoxControls to contain my CheckBoxes, but it's empty.
    var checkBoxControls = gridView.Rows[e.NewEditIndex].FindControl("countriesPlaceHolder").Controls;

    gridView.EditIndex = e.NewEditIndex;
    BindData();
}

protected void gridView_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
    // EXAMPLE: I'm expecting checkBoxControls to contain my CheckBoxes, but it's empty.
    var checkBoxControls = ((PlaceHolder)gridView.Rows[e.RowIndex].FindControl("countriesPlaceHolder")).Controls;

    // This is where I'd grab the values from the controls, create an entity, and save the entity to the database.

    gridView.EditIndex = -1;
    BindData();
}

这是我为数据绑定方法所遵循的文章:http://www.aarongoldenthal.com/post/2009/04/19/Manually-Databinding-a-GridView.aspx

1 个答案:

答案 0 :(得分:1)

您需要在页面加载时调用BindData()方法。

“由于控件的工作方式,需要在每个页面加载时重新创建动态控件或列。动态控件不会被保留,因此您必须在每个页面回发时重新加载它们;但是,将保留viewstate用于这些控制“。

请参阅Cells in gridview lose controls on RowUpdating event

同样在您链接的文章中,有一个ItemTemplate和一个EditItemTemplace,因为它们有不同的显示,即只读和可编辑。你的是相同的,所以我认为你可以简化你的设计:

<asp:GridView ID="gridView" runat="server" AutoGenerateColumns="False" DataKeyNames="ID" ondatabound="gridView_DataBound">
<Columns>
    <asp:TemplateField HeaderText="Countries">
        <ItemTemplate>
            <asp:PlaceHolder ID="countriesPlaceHolder" runat="server"></asp:PlaceHolder>
        </ItemTemplate>
    </asp:TemplateField>
    <asp:TemplateField ShowHeader="False">
        <ItemTemplate>
            <asp:LinkButton ID="editButton" runat="server" Text="Edit" onclick="editButton_Click" ></asp:LinkButton>
            <asp:LinkButton ID="updateButton" runat="server" Text="Update" onclick="updateButton_Click" ></asp:LinkButton>
        </ItemTemplate>
    </asp:TemplateField>
</Columns>
</asp:GridView>

代码背后:

    protected void gridView_DataBound(object sender, EventArgs e)
    {
        // Loop through the Holidays that are bound to the GridView
        var holidays = (IEnumerable<Holiday>)gridView.DataSource;
        for (int i = 0; i < holidays.Count(); i++)
        {
            // Get the row the Holiday is bound to
            GridViewRow row = gridView.Rows[i];
            // Get the PlaceHolder control
            var placeHolder = (PlaceHolder) row.FindControl("countriesPlaceHolder");
            var countryCheckBox = new CheckBox
                                      {
                                          Checked = true,
                                          ID = "auCheckBox",
                                          Text = "Aus",
                                          Enabled = false
                                      };
            placeHolder.Controls.Add(countryCheckBox);

            var editButton = (LinkButton)row.FindControl("editButton");
            editButton.CommandArgument = i.ToString();
            var updateButton = (LinkButton)row.FindControl("updateButton");
            updateButton.CommandArgument = i.ToString();
            updateButton.Visible = false;
        }
    }

    protected void editButton_Click(object sender, EventArgs e)
    {
        LinkButton editButton = (LinkButton) sender;
        int index = Convert.ToInt32(editButton.CommandArgument);

        GridViewRow row = gridView.Rows[index];
        // Get the PlaceHolder control
        LinkButton updateButton = (LinkButton)row.FindControl("updateButton");
        updateButton.Visible = true;
        editButton.Visible = false;

        CheckBox checkbox = (CheckBox)row.FindControl("auCheckBox");
        if (checkbox != null)
        {
            checkbox.Enabled = true;
            // Get value and update
        }
    }

    protected void updateButton_Click(object sender, EventArgs e)
    {
        LinkButton updateButton = (LinkButton)sender;
        int index = Convert.ToInt32(updateButton.CommandArgument);

        GridViewRow row = gridView.Rows[index];
        // Get the PlaceHolder control
        LinkButton editButton = (LinkButton)row.FindControl("updateButton");
        editButton.Visible = true;
        updateButton.Visible = false;

        CheckBox checkbox = (CheckBox)row.FindControl("auCheckBox");
        if (checkbox != null)
        {
            // Get value and update

            checkbox.Enabled = false;
        }
    }

如果您希望从get go启用它,只需删除启用的检查,您就可以删除编辑按钮。

希望有所帮助。