Gridview Row Events not firing in UserControl

2019-07-20 22:01发布

I've got a pretty strange problem with my usercontrols that I'm working with. I'm coding some user controls to be used in a DotNetNuke module.

Basically I have a UserControl on my page that holds some controls and then there is a Placeholder where I am loading in a UserControl that has a GridView placed in it.

Basically here is my page structure

<asp:Panel runat="server" ID="pnlServiceType" Visible="false">
   <uc:ServiceType runat="server" ID="ServiceType" />
</asp:Panel>

Within that user control are some form elements and then the following:

<asp:PlaceHolder runat="server" ID="phServices" />

That placeholder then has a user control added to it like so:

<p class="header"><asp:Label runat="server" ID="lblServiceHeader" Font-Bold="true" /></p>

<asp:GridView runat="server" ID="gvServices" AlternatingRowStyle-BackColor="#eaeaea"  BorderStyle="None" GridLines="None"
AutoGenerateColumns="false" CellPadding="6" Width="100%" EnableViewState="false" OnRowEditing="gvServices_RowEditing">

When the user picks something in the DropDownList, I'm clearing the controls out of the Placeholder, and re-adding just a single UserControl for the set of records for whatever type they've picked like so

        _serviceID = e.Value;

        //Clear the controls out of the placeholder
        phServices.Controls.Clear();

        //Reset the count of grids for the OnInit() method
        Session["GridCount"] = 0;

        if (e.Value != "NULL")
        {
            PopulateServicesGrid(_service.GetServicesByFormType(Convert.ToInt32(e.Value)));
        }
        else
        {
            PopulateServicesGrid(_service.GetServicesByClient(Convert.ToInt32(_client)));
        }

And the PopulateServicesGrid method:

    private void PopulateServicesGrid(List<NOAService> services)
    {
        //Creates a LINQ grouping based on the Billing Codes
        //Allows a super easy creation of grids based on the grouped billing codes
        var query = services.Select(service => service.BillingCode).Distinct();
        foreach (string code in query)
        {
            var servicesByCode = services.Where(service => service.BillingCode == code).ToList();
            ServicesGrid servicesGrid = LoadControl("~/DesktopModules/LEL Modules/NOA/ServicesGrid.ascx") as ServicesGrid;
            Label lblServiceHeader = servicesGrid.FindControl("lblServiceHeader") as Label;
            GridView gvServices = servicesGrid.FindControl("gvServices") as GridView;

            phServices.Controls.Add(servicesGrid);
            servicesGrid.ID = code;
            lblServiceHeader.Text = servicesByCode[0].FormTypeName;
            gvServices.DataSource = servicesByCode;
            gvServices.DataBind();

            Session["GridCount"] = phServices.Controls.Count;

        }
    }

And on my ServiceType UserControl, on the PageInit, I'm readding the ServiceGrid usercontrol so that my grids show up across postbacks and aren't lost from the Placeholder

    void NOAServiceType_Init(object sender, EventArgs e)
    {
        for (int i = 0; i < Convert.ToInt32(Session["GridCount"]); i++)
        {
            ServicesGrid servicesGrid = LoadControl("~/DesktopModules/LEL Modules/NOA/ServicesGrid.ascx") as ServicesGrid;
            phServices.Controls.Add(servicesGrid);

        }
    }

The grids populate successfully and everything seems to work just fine. But for some reason, on my GridView, I have a CommandField of

    <asp:CommandField ShowEditButton="true" ItemStyle-HorizontalAlign="Right" EditText="Edit" UpdateText="Update" 
        EditImageUrl="~/images/LELModules/appbar.edit.rest.png" CancelImageUrl="~/images/LELModules/appbar.close.rest.png" UpdateImageUrl="~/images/LELModules/appbar.check.rest.png"
        ButtonType="Image" CausesValidation="false" />

When I click my Edit command on the Grid row, nothing happens. My grid doesn't lose its rows, the control is still there, everything seems like it should be ok. The RowEditing event doesn't fire until I click it a second time.

Any idea why this might be occuring?

UPDATE: I've managed to figure out that my SelectedIndexChanged handlers are effectively resetting the DataSource on the Grid contained by the UserControl when they are readded to the PlaceHolder. When the CommandField (Edit) is clicked though, the Init fires for the UserControl that holds the placeholder

ServiceType UserControl < `Init` fires here
   -Form elements
   -Placeholder which holds
      --UserControl with GridView

The Init method loads up new instances of the UserControl and adds them to the PlaceHolder, but the DataSource is null. With EnableViewState=true it looks like the data is still bound, but if I handle PreRender, I can see that the DataSource on my gvServices | null

Is it even possible to edit rows like this on a GridView that is being added dynamically to a PlaceHolder over and over?

FIXED I found out what the issue was after referring to this article http://www.west-wind.com/weblog/posts/2006/Feb/24/Overriding-ClientID-and-UniqueID-on-ASPNET-controls

It got me thinking, what if the IDs were getting changed? The controls are way nested. So I went and put a watch on the GridView's ID, ClientID, and UniqueID just to see. When the Control is loaded on my Init handler, it's assigned a super generic ID when it's added.

private void PopulateServicesGrid(List<NOAService> services)
{
    //Creates a LINQ grouping based on the Billing Codes
    //Allows a super easy creation of grids based on the grouped billing codes
    var query = services.Select(service => service.BillingCode).Distinct();
    foreach (string code in query)
    {
        var servicesByCode = services.Where(service => service.BillingCode == code).ToList();
        ServicesGrid servicesGrid = LoadControl("~/DesktopModules/LEL Modules/NOA/ServicesGrid.ascx") as ServicesGrid;
        Label lblServiceHeader = servicesGrid.FindControl("lblServiceHeader") as Label;
        GridView gvServices = servicesGrid.FindControl("gvServices") as GridView;

        phServices.Controls.Add(servicesGrid);
        **servicesGrid.ID = code;**
        lblServiceHeader.Text = servicesByCode[0].FormTypeName;
        gvServices.DataSource = servicesByCode;
        gvServices.DataBind();

        Session["GridCount"] = phServices.Controls.Count;

    }
}

I was setting the ID as something else. So when I was hitting the Edit RowCommand on my grid, it was reloading the controls again on Init and the IDs were being changed back from my custom set code (T2020, pulled from my database) to the generic ID again, it didn't know how to fire the event.

I hope this helps someone as I've lost at least 12 hours fixing this problem.

0条回答
登录 后发表回答