Asp.net 带有下拉列表的 gridview:Rowindex 在 SelectedIndexChanged 事件中始终为 0

Asp.net gridview with dropdown: Rowindex is always 0 in SelectedIndexChanged event

我遇到了一个让我抓狂的问题。任何帮助将非常感激。我有一个网格视图,显示哪些研究项目分配给了哪些人。应该可以使用下拉菜单更改分配。这是标记:

<asp:GridView ID="assignmentsGridView" runat="server" AutoGenerateColumns="false" CellPadding="2" Font-Size="Smaller" 
OnRowDataBound="assignmentsGridView_RowDataBound" OnRowCommand="assignmentsGridView_RowCommand">
<Columns>
    <asp:BoundField HeaderText="Ticker" DataField="Item" />
    <asp:BoundField HeaderText="Name" DataField="Name" />
    <asp:TemplateField HeaderText="Assignment" ItemStyle-HorizontalAlign="Center" ControlStyle-Font-Size="Small">
        <ItemTemplate>
            <asp:DropDownList ID="assignmentDropDown" runat="server" Visible="true"
                OnSelectedIndexChanged="assignmentDropDown_SelectedIndexChanged" AutoPostBack="true" >
                <asp:ListItem Text="Joe" Value="Joe"></asp:ListItem>
                <asp:ListItem Text="Aron" Value="Aron"></asp:ListItem>
                <asp:ListItem Text="Frank" Value="Frank"></asp:ListItem>
                <asp:ListItem Text="Ross" Value="Ross"></asp:ListItem>
                <asp:ListItem Text="Alex" Value="Alex"></asp:ListItem>
            </asp:DropDownList>
        </ItemTemplate>
    </asp:TemplateField>
    <asp:BoundField HeaderText="Analyst Complete" DataField="AnalystComplete" ItemStyle-HorizontalAlign="Center" ControlStyle-Font-Size="Smaller"/>
    <asp:TemplateField HeaderText="Mark Complete" ControlStyle-Font-Size="Smaller">
        <ItemTemplate>
            <asp:Button ID="completeButton" runat="server" Text="Incomplete" CommandArgument='<%# Eval("Item") %>' 
                CommandName="Complete" Font-Size="Smaller" />

        </ItemTemplate>
    </asp:TemplateField>

</Columns>
</asp:GridView>

我想在用户更改下拉列表的 SelectedIndex 时更新数据库。我在这里处理:

protected void assignmentDropDown_SelectedIndexChanged(object sender, EventArgs e)
{
    if (Session["IsCompany"] == null)
    {
        Session["IsCompany"] = assignmentsDropDown.SelectedValue == "Company";
    }
    bool? isCompany = Session["IsCompany"] as bool?;
    int isCo = (isCompany == true) ? 1 : 0;

    DropDownList ddl = sender as DropDownList;
    GridViewRow gvr = ddl.NamingContainer as GridViewRow;
    //ri is always 0!
    int ri = gvr.RowIndex;
    gvr = (GridViewRow)(((Control)sender).NamingContainer);
    //ri is always 0!
    ri = gvr.RowIndex;
    gvr = ((GridViewRow)ddl.Parent.Parent);
    //ri is always 0!
    ri = gvr.RowIndex;

    string selAnalyst = ddl.SelectedValue;
    //selAnalsyt always = initial value!
    selAnalyst = ddl.SelectedItem.Value;
    //selAnalsyt always = initial value!
    string ticker = gvr.Cells[0].Text;
    //ticker always is first data row
}

正如您在评论中看到的那样,无论我单击哪一行,与 sender 参数关联的 GridViewRow 始终是第一行。此外,下拉列表的选定值始终是其初始值,而不是触发 SelectedIndexChanged 事件的用户选择的值。

我在网上搜索了这个问题的解决方案,发现它通常是由 (1) 在回发时触发数据绑定事件和 (2) 源数据中的重复行引起的。我检查了重复数据并解决了该问题,并将主键放在适当的 table 上。我还要确保不要在回发时重新绑定数据。这是 Page_Load 方法:

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.User.Identity.IsAuthenticated)
    {
        FormsAuthentication.RedirectToLoginPage();
    }
    else
    {
        string userName = Page.User.Identity.Name;
        if (Session["UserMod"] == null)
        {
            this.userMod = new userModel(userName);
        }
        else
        {
            this.userMod = Session["UserMod"] as userModel;
        }

        if (!IsPostBack)
        {
            getPeopleList(userName);
            getTickerList(userName);


            if (this.userMod.IsResearchAdmin)
            {
                getAdminList();
            }
            else 
            {

                assignmentsDropDown.Visible = false;
                assignmentsGridView.Visible = false;
                assignmentsButton.Visible = false;
                assignmentsLabel.Visible = false;
                addTextBox.Visible = false;
                Image1.Visible = true;
                analystDropdown.Visible = false;
            }
        }
    }
}

我还有一个 RowDataBound 方法,它为每一行设置下拉列表的选定值。调试时,我已验证该方法仅在初始页面加载时为 运行,而不是在从 SelectedIndexChanged 回发之后。我也在使用更新面板,但在尝试调试时删除了它。

我现在完全没有想法,所以我愿意接受任何建议。提前致谢

看来我发现了 asp.net 的一个奇怪的特质。我在 RowDataBound 方法中有以下代码:

if (IsCompany)
    {
        e.Row.Cells.Remove(e.Row.Cells[1]);
    }

我删除了这段代码,下拉 SelectedIndexChanged 方法现在可以正常工作。更改 RowDataBound 方法后,获取下拉列表的父 GridViewRow 的所有 3 种方法都有效,因此它不会删除 gridview 中的任何单元格。

我现在相信在数据绑定期间添加或删除单元格会导致 GridView 中下拉菜单的 SelectedIndexChanged 事件出现意外问题。以下是 RowDataBoundMethod 的完整代码:

protected void assignmentsGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (Session["IsCompany"] == null)
    {
        Session["IsCompany"] = entityDropDown.SelectedValue == "Company";
    }
    bool? isCompany = Session["IsCompany"] as bool?;
    bool IsCompany = (bool)isCompany;

    TableCell cell;
    if (e.Row.RowType == DataControlRowType.DataRow)
    {

        cell = e.Row.Cells[0];
        HyperLink link = new HyperLink();
        if (IsCompany)
        {
            link.NavigateUrl = "~/CompanyPage.aspx?Ticker=" + cell.Text;
        }
        else
        {
            link.NavigateUrl = "~/PeoplePage.aspx?PersonId=" + cell.Text;
        }
        link.Text = cell.Text;
        cell.Controls.Clear();
        cell.Controls.Add(link);
        /* with this code included, I experience problems with the SelectedIndexChanged event of the dropdown
        if (IsCompany)
        {
            e.Row.Cells.Remove(e.Row.Cells[1]);
        }
        */

        cell = e.Row.Cells[2];

        var dd = e.Row.FindControl("assignmentDropDown") as DropDownList;
        string assignment = ((DataRowView)e.Row.DataItem)["Assignment"].ToString();
        foreach (ListItem li in dd.Items)
        {
            if (li.Value == assignment)
            {
                li.Selected = true;
                break;
            }
        }
        cell = e.Row.Cells[4];
        if (cell.Text == "False")
        {
            //"completeButton"
            var cb = e.Row.FindControl("completeButton") as Button;
            cb.Enabled = false;
            cb.Visible = false;
        }
        else
        {
            ((Button)cell.FindControl("completeButton")).CommandArgument = e.Row.RowIndex.ToString();
        }
    }
}

如果有人可以确认删除 rowdatabound 中的单元格会导致 asp.net 中选定的索引更改事件出现问题,我将不胜感激。