События строки Gridview не запускаются в UserControl

У меня довольно странная проблема с моими пользовательскими элементами управления, с которыми я работаю. Я кодирую некоторые пользовательские элементы управления для использования в модуле DotNetNuke.

В основном у меня есть UserControl на моей странице, который содержит некоторые элементы управления, а затем есть Placeholder, где я загружаю UserControl, в котором размещен GridView.

В основном вот моя структура страницы

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

Внутри этого пользовательского элемента управления находятся некоторые элементы формы, а затем следующее:

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

Затем к этому заполнителю добавляется пользовательский элемент управления, например:

<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">

Когда пользователь выбирает что-то в DropDownList, я удаляю элементы управления из Placeholder и повторно добавляю только один UserControl для набора записей для любого типа, который они выбрали, вот так

        _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)));
        }

И метод PopulateServicesGrid:

    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;

        }
    }

И в моем UserControl ServiceType, в PageInit, я читаю пользовательский элемент управления ServiceGrid, чтобы мои сетки отображались при обратных передачах и не терялись из заполнителя.

    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);

        }
    }

Сетки успешно заполняются, и все работает нормально. Но по какой-то причине в моем GridView у меня есть CommandField из

    <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" />

Когда я нажимаю команду «Редактировать» в строке «Сетка», ничего не происходит. Моя сетка не теряет ряды, управление осталось, вроде все должно быть ок. Событие RowEditing не срабатывает, пока я не щелкну его второй раз.

Любая идея, почему это может происходить?

ОБНОВЛЕНИЕ: мне удалось выяснить, что мои обработчики SelectedIndexChanged эффективно сбрасывают DataSource в сетке, содержащейся в UserControl, когда они считываются в PlaceHolder. Однако при нажатии CommandField (Edit) Init срабатывает для UserControl, который содержит заполнитель

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

Метод Init загружает новые экземпляры UserControl и добавляет их в PlaceHolder, но источником данных является null. С EnableViewState=true данные все еще привязаны, но если я обработаю PreRender, я увижу, что DataSource на моем gvServices | null

Можно ли вообще редактировать такие строки в GridView, который динамически добавляется в PlaceHolder снова и снова?

ИСПРАВЛЕНО Я узнал, в чем проблема, прочитав эту статью http://www.west-wind.com/weblog/posts/2006/Feb/24/Overriding-ClientID.-and-UniqueID-on-ASPNET-controls

Это заставило меня задуматься, а что, если идентификаторы менялись? Элементы управления вложены друг в друга. Поэтому я пошел и посмотрел на идентификатор GridView, ClientID и UniqueID, просто чтобы посмотреть. Когда элемент управления загружается в мой обработчик Init, при добавлении ему присваивается суперобщий идентификатор.

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;

    }
}

Я устанавливал идентификатор как что-то еще. Поэтому, когда я нажимал Edit RowCommand в своей сетке, он снова перезагружал элементы управления на Init, и идентификаторы менялись обратно с моего кода пользовательского набора (T2020, извлеченный из моей базы данных) на общий идентификатор снова, это не знать, как запустить событие.

Я надеюсь, что это поможет кому-то, поскольку я потерял не менее 12 часов, решая эту проблему.


person dgarbacz    schedule 04.04.2012    source источник