【问题标题】:Dropdown_SelectedIndexchange event fires for all rows in gridview下拉 SelectedIndexchanged 事件触发 gridview 中的所有行
【发布时间】:2013-01-30 09:05:36
【问题描述】:

我有每行包含下拉列表的gridview。下拉列表已选择索引更改事件。现在,当我在网格的任何行中更改下拉列表中的值时,它会为 gridview 中的所有行触发选定的索引更改事件。 如何解决这个问题?

下面是 HTML 标记

<asp:GridView ID="gvEditFields" runat="server" 
                        AllowSorting="false" AllowPaging="false" OnRowDataBound="gvEditFields_RowDataBound" >
                        <Columns>
                            <asp:TemplateField HeaderText="Project">
                                <ItemTemplate>
                                    <asp:DropDownList ID="ddlProjectList" runat="server" Width="130px" AutoPostBack="true"  OnSelectedIndexChanged="ddlProjectList_SelectedIndexChanged"></asp:DropDownList>
                                    <asp:RequiredFieldValidator ID="rfvProjectList" runat="server" ErrorMessage="* Required"
                                        Display="Dynamic" ControlToValidate="ddlProjectList" SetFocusOnError="True" ValidationGroup="EditGridSave"
                                        Text="Required" ></asp:RequiredFieldValidator>
                                </ItemTemplate>
                            </asp:TemplateField>
                            <asp:TemplateField HeaderText="Task">
                                <ItemTemplate>
                                    <asp:DropDownList ID="ddlTaskList" runat="server" AppendDataBoundItems="false" Width="150px" OnSelectedIndexChanged="ddlTaskList_SelectedIndexChanged"></asp:DropDownList>
                                    <asp:RequiredFieldValidator ID="rfvTaskList" runat="server" ErrorMessage="* Required"
                                        Display="Dynamic" ControlToValidate="ddlTaskList" SetFocusOnError="True" ValidationGroup="EditGridSave"
                                        Text="Required" ></asp:RequiredFieldValidator>
                                </ItemTemplate>
                            </asp:TemplateField>
                            <asp:TemplateField HeaderText="Task Status">
                                <ItemTemplate>
                                    <asp:DropDownList ID="ddlTaskStatus" runat="server"  Width="100px"></asp:DropDownList>
                                    <asp:RequiredFieldValidator ID="rfvTaskStatus" runat="server" ErrorMessage="* Required"
                                        Display="Dynamic" ControlToValidate="ddlTaskStatus" SetFocusOnError="True" ValidationGroup="EditGridSave"
                                        Text="Required" ></asp:RequiredFieldValidator>
                                </ItemTemplate>
                            </asp:TemplateField>
                            <asp:TemplateField HeaderText="Description">
                                <ItemTemplate>
                                    <asp:TextBox ID="txtDescription" runat="server" TextMode="MultiLine" Rows="3" Columns="30" />
                                </ItemTemplate>
                            </asp:TemplateField>
                        </Columns>
                    </asp:GridView>

这是行数据绑定和选定索引更改事件的代码。

protected void gvEditFields_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        SetEditFieldsGridRecords(e.Row);
        //DropDownList ddlProjectList = (DropDownList)e.Row.FindControl("ddlProjectList");

    }
}

protected void ddlProjectList_SelectedIndexChanged(object sender, EventArgs e)
{        
    DropDownList ddlProjectList = (DropDownList)sender;
   // GridViewRow Row = (GridViewRow)ddlProjectList.NamingContainer;
    GridViewRow selectedRow = (GridViewRow)ddlProjectList.Parent.Parent;
    int i = selectedRow.RowIndex;
    DropDownList ddlTaskList = (DropDownList)selectedRow.Cells[1].FindControl("ddlTaskList");
    DropDownList ddlTaskStatus = (DropDownList)selectedRow.Cells[2].FindControl("ddlTaskStatus");

    BindTasks(clsCheckDBNull.ToStr(ddlProjectList.SelectedValue), -1, ddlTaskList);
    BindStatus(clsCheckDBNull.ToInt(ddlTaskList.SelectedValue), "", ddlTaskStatus);

}

下面是使用方法的代码

private void BindStatus(int intTaskId, string TaskStatus, DropDownList drpStatus)
{
    DataTable dt = clsProjectTaskStatuses.SelectAll(BTMSession.AccountID);
    DataView dv = new DataView(dt);
    drpStatus.DataTextField = "str_PROJECT_TASK_STATUS_NAME";
    drpStatus.DataValueField = "int_PROJECT_TASK_STATUS_ID";
    drpStatus.DataSource = dv;
    drpStatus.DataBind();
    SiteUtility.BindTooltip(drpStatus);

    if (drpStatus.Items.Count >= 2 && TaskStatus.Trim() != "")
    {
        if (drpStatus.Items.FindByText(TaskStatus.ToString()) != null)
            drpStatus.SelectedIndex = drpStatus.Items.IndexOf(drpStatus.Items.FindByText(TaskStatus.ToString()));
    }
}

private void BindTasks(string ProjectNo, int intTaskid, DropDownList drpTasks)
{
    if (drpTasks.Items.Count >= 1)
        drpTasks.Items.Clear();
    DataSet ds = new DataSet();

    clsImportFileTypeDAL objImportFileTypeDAL = new clsImportFileTypeDAL();
    ds = objImportFileTypeDAL.SelectTaskListByProjectNoUserIDForTimeImport(ProjectNo, clsCheckDBNull.ToInt(BTMSession.UserId));
    CommonHelper.DisposeOf(objImportFileTypeDAL);

    if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
    {
        drpTasks.DataTextField = "str_TASK_SUMMERY";
        drpTasks.DataValueField = "int_task_id";
        drpTasks.DataSource = ds;
        drpTasks.DataBind();
    }

    drpTasks.Items.Insert(0, new ListItem("Select Task", "-1"));
    SiteUtility.BindTooltip(drpTasks);
    drpTasks.SelectedValue = "-1";

    if (drpTasks.Items.Count >= 2)
    {
        if (drpTasks.Items.FindByValue(intTaskid.ToString()) != null)
            drpTasks.SelectedIndex = drpTasks.Items.IndexOf(drpTasks.Items.FindByValue(intTaskid.ToString()));
    }
}

private void SetEditFieldsGridRecords(GridViewRow 行) { DataRowView drv = (DataRowView)row.DataItem;

    DropDownList ddlProjectList = (DropDownList)row.FindControl("ddlProjectList");
    BindProjects(clsCheckDBNull.ToStr(drv["str_PROJECT_NO"]), ddlProjectList);

    DropDownList ddlTaskList = (DropDownList)row.FindControl("ddlTaskList");
    BindTasks(ddlProjectList.SelectedValue, clsCheckDBNull.ToInt(drv["int_TASK_NO"]), ddlTaskList);

    DropDownList ddlTaskStatus = (DropDownList)row.FindControl("ddlTaskStatus");
    BindStatus(clsCheckDBNull.ToInt(ddlTaskList.SelectedValue), clsCheckDBNull.ToStr(drv["TaskStatus"]), ddlTaskStatus);

    BTMWeb.Calender.Calender txtWorkDate = (BTMWeb.Calender.Calender)row.FindControl("txtWorkDate");
    DropDownList drpStartHours = (DropDownList)row.FindControl("drpStartHours");
    DropDownList drpStartMinutes = (DropDownList)row.FindControl("drpStartMinutes");
    DropDownList drpEndHours = (DropDownList)row.FindControl("drpEndHours");
    DropDownList drpEndMinutes = (DropDownList)row.FindControl("drpEndMinutes");
    TextBox txtDescription = (TextBox)row.FindControl("txtDescription");

    int StartHours = clsCheckDBNull.ToDate(drv["StartTime"]).Hour;
    int StartMinutes = clsCheckDBNull.ToDate(drv["StartTime"]).Minute;
    int EndHours = clsCheckDBNull.ToDate(drv["EndTime"]).Hour;
    int EndMinutes = clsCheckDBNull.ToDate(drv["EndTime"]).Minute;

    txtWorkDate.DateValue = clsCheckDBNull.ToDate(drv["dt_WORKDATE"]);
    drpStartHours.SelectedValue = StartHours.ToString();
    drpStartMinutes.SelectedValue = StartMinutes.ToString();
    drpEndHours.SelectedValue = EndHours.ToString();
    drpEndMinutes.SelectedValue = EndMinutes.ToString();

    txtDescription.Text = clsCheckDBNull.ToStr(drv["str_Description"]);

}

例如。如果我有行并且如果我更改了第一行中的下拉值,则所选的索引更改会针对这两行触发。

【问题讨论】:

  • 请分享您的代码..
  • 您如何确定它“为 gridview 中的所有行触发选定的索引更改事件”?无论如何,这到底意味着什么?
  • 请不要分享您的全部代码。分享一个简要简洁 sn-p,例如,下拉列表中的标记、连接事件处理程序的代码段以及事件处理程序本身。
  • 请检查问题。我添加了代码

标签: c# asp.net gridview selectedindexchanged


【解决方案1】:

只有一两个改进建议:

  • 使用NamingContainer 属性来获取对GridViewRow 的引用,而不是Paret.Parent,因为Paret.Parent 本身就容易出错(例如,如果您使用TemplateField 中的控件,即容器控件。

所以而不是:

GridViewRow selectedRow = (GridViewRow)ddlProjectList.Parent.Parent;

这个

GridViewRow selectedRow = (GridViewRow)ddlProjectList.NamingContainer;
  • 与此相关:始终在您要查找的控件的NamingContainer 上使用FindControl,即GridViewRow 在这种情况下,TableCell 没有实现INamingContainer

所以而不是:

DropDownList ddlTaskList = (DropDownList)selectedRow.Cells[1].FindControl("ddlTaskList");

这个

DropDownList ddlTaskList = (DropDownList)selectedRow.FindControl("ddlTaskList");

这更不容易出错。

旁注:不清楚为什么需要像CommonHelper.DisposeOf 这样的方法。 我假设你会在BindTasksBindStatus 中找到核心问题。你能告诉他们吗?

【讨论】:

  • 你能提供这个问题的解决方案吗..?
  • @ChiragFanse:你看到我回答的最后一句话了吗?顺便说一句,你为什么显示RowDataBound而不显示SetEditFieldsGridRecords
  • ..哦对不起。顺便说一句,你已经添加了代码中使用的所有方法。请再次查看
  • @ChiragFanse:抱歉,我没有找到明显的原因。事件处理程序是为每一行调用两次还是真的被调用(如果GridView 包含更多行)。事件处理程序是在同一个请求中触发还是在下一次回发中触发?您是否仅在 !IsPostBack 时才从 page_load 对 GridView 进行数据绑定?
  • 是的,事件处理程序调用了两次,它在同一个请求上触发。我在页面加载、事件入口和事件出口处保留断点。页面加载后,控制进入事件入口,然后是事件主体和事件出口。从事件出口再次进入事件入口。我在 !IsPostBack 中绑定网格。
猜你喜欢
  • 1970-01-01
  • 2010-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-11
相关资源
最近更新 更多