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 中选定的索引更改事件出现问题,我将不胜感激。
我遇到了一个让我抓狂的问题。任何帮助将非常感激。我有一个网格视图,显示哪些研究项目分配给了哪些人。应该可以使用下拉菜单更改分配。这是标记:
<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 中选定的索引更改事件出现问题,我将不胜感激。