Search code examples
c#asp.netdatagridevent-handling

DataGrid OnItemDataBound is interfering with DropDownList OnSelectedIndexChange Event


I have an ASP.Net 4.6.1 web page with a DataGrid. Inside the DataGrid, in a TemplateColumn, I have a DropDownList. The DropDownList has an OnSelectedIndexChanged event handler:

<asp:DataGrid runat="server" ID="dgPartnerApprovalPending" DataKeyField="OrderID" 
                       CellPadding="10" CellSpacing="10" AlternatingItemStyle-BackColor="WhiteSmoke" HeaderStyle-BackColor="WhiteSmoke" AutoGenerateColumns="false" 
                        AllowSorting="true" OnSortCommand="dgPartnerApprovalPending_SortCommand">
                        <Columns>
                            <asp:BoundColumn DataField="AttorneyName" HeaderText="Attorney Name" SortExpression="AttorneyName" />
                            <asp:BoundColumn DataField="Title" HeaderText="Title" SortExpression="Title" />
                            <asp:BoundColumn DataField="Description" HeaderText="Description" SortExpression="Description" />
                            <asp:BoundColumn DataField="RequestDate" HeaderText="Request Date" SortExpression="RequestDate" />
                            <asp:BoundColumn DataField="TotalAmount" HeaderText="Total Amount" SortExpression="TotalAmount" />
                            <asp:BoundColumn DataField="OrderStatus" HeaderText="Order Status" SortExpression="OrderStatus" />
                            <asp:TemplateColumn HeaderText="Status">
                                <ItemTemplate>
                                    <asp:DropDownList runat="server" ID="ddlStatus" OnSelectedIndexChanged="ddlStatus_SelectedIndexChanged" AutoPostBack="true" 
                                        DataSourceID="sdsStatuses" DataTextField="OrderStatus" DataValueField="OrderStatusID" /> 
                                </ItemTemplate>
                            </asp:TemplateColumn>
                            <asp:BoundColumn DataField="OrderID" HeaderText="Order ID" SortExpression="OrderID" />
                            <asp:HyperLinkColumn Text="Files" DataNavigateUrlField="OrderID" DataNavigateUrlFormatString="~/Files/{0}" />
                        </Columns>
                    </asp:DataGrid>

The OnSelectedIndexChanged event handler works fine UNTIL I add an OnItemDataBound event handler to the DataGrid:

<asp:DataGrid runat="server" ID="dgPartnerApprovalPending" DataKeyField="OrderID" OnItemDataBound="dgPartnerApprovalPending_ItemDataBound" 
                       CellPadding="10" CellSpacing="10" AlternatingItemStyle-BackColor="WhiteSmoke" HeaderStyle-BackColor="WhiteSmoke" AutoGenerateColumns="false" 
                        AllowSorting="true" OnSortCommand="dgPartnerApprovalPending_SortCommand">
                        <Columns>
                            <asp:BoundColumn DataField="AttorneyName" HeaderText="Attorney Name" SortExpression="AttorneyName" />
                            <asp:BoundColumn DataField="Title" HeaderText="Title" SortExpression="Title" />
                            <asp:BoundColumn DataField="Description" HeaderText="Description" SortExpression="Description" />
                            <asp:BoundColumn DataField="RequestDate" HeaderText="Request Date" SortExpression="RequestDate" />
                            <asp:BoundColumn DataField="TotalAmount" HeaderText="Total Amount" SortExpression="TotalAmount" />
                            <asp:BoundColumn DataField="OrderStatus" HeaderText="Order Status" SortExpression="OrderStatus" />
                            <asp:TemplateColumn HeaderText="Status">
                                <ItemTemplate>
                                    <asp:DropDownList runat="server" ID="ddlStatus" OnSelectedIndexChanged="ddlStatus_SelectedIndexChanged" AutoPostBack="true" 
                                        DataSourceID="sdsStatuses" DataTextField="OrderStatus" DataValueField="OrderStatusID" /> 
                                </ItemTemplate>
                            </asp:TemplateColumn>
                            <asp:BoundColumn DataField="OrderID" HeaderText="Order ID" SortExpression="OrderID" />
                            <asp:HyperLinkColumn Text="Files" DataNavigateUrlField="OrderID" DataNavigateUrlFormatString="~/Files/{0}" />
                        </Columns>
                    </asp:DataGrid>

And here's the code that's called when the ItemDataBound event is triggered:

protected void dgPartnerApprovalPending_ItemDataBound(object sender, DataGridItemEventArgs e)
    {
        ListItemType itemType = (ListItemType)e.Item.ItemType;           

        if (itemType == ListItemType.Item || itemType == ListItemType.AlternatingItem)
        {
            DataRowView view = (DataRowView)e.Item.DataItem;
            string OrderID = view["OrderID"].ToString();

            for (int i = 0; i <= 6; i++)
            {
                e.Item.Cells[i].Attributes.Add("OnClick", "window.location.href='PartnerApprovalDetail.aspx?oid="
                + OrderID
                + "'"
                );
            }
        }
    }

In short, the ItemDataBound event makes each row clickable, and redirects the user to a different page. Once I add this event handler and load the page, whenever I click on the DropDownList in any row, the page goes blank. If I do this in the debugger, the SelectedIndexChanged event is never triggered. I've tried binding data to the DropDownList in the OnItemDataBound handler after the rows are made clickable. I've also tried binding data to the DropDownList in PageLoad() after a PostBack. Neither helps. How do I get around this?


Solution

  • You are adding onclick event handler at table cell <td> and the dropdown is rendered inside the table cell.So, when you try to click on the dropdown the click event is caught at by the event handler defined at parent table cell level which nvaigates the user away.

    You can create a new template column for rendering the Detail link:

        <asp:TemplateColumn HeaderText="Status">
           <ItemTemplate>
              <asp:HyperLink ID="DetailsUrls" runat="server" href="PartnerApprovalDetail.aspx?oid=<%#Eval("OrderID")%>">Detail</asp:HyperLink>
          </ItemTemplate>
        </asp:TemplateColumn>