选定索引已更改事件未在子控件中触发
本文关键字:控件 事件 索引 | 更新日期: 2023-09-27 18:32:39
我有一个 asp.net 控件,当按下按钮时,它引用了一个用户控件(弹出窗口(。 按下按钮时,我在弹出用户控件中找到下拉列表,并设置它的选定值。
protected void btnMyBUtton_Click(object sender, EventArgs args)
{
pnlUserControl_ModalPopupExtender.Show();
if (ddParent.SelectedIndex > 0)
{
DropDownList dd = ucMyControl.FindControlRecursive("ddChild") as DropDownList;
dd.SelectedValue = ddParent.SelectedValue;
}
}
在弹出用户控件中,我预计 SelectedIndexChanged 事件会触发。然而,事实并非如此。 知道为什么会这样吗?
我的子控件(仅相关代码(的标记如下:
<asp:FormView ID="myForm" runat="server" DataSourceID="dsMyDS" DefaultMode="Insert">
<EditItemTemplate>
<asp:Panel runat="server">
<table>
<tr>
<td>
<asp:Label Text="Name" runat="server" /></td>
<td>
<asp:DropDownList ID="ddChild" runat="server" DataSourceID="ddDS" DataMember="" DataValueField="Id" DataTextField="Name" SelectedValue='<%# Bind("Id") %>' AutoPostBack="true" OnSelectedIndexChanged="ddChild_SelectedIndexChanged" OnDataBound="ddChild_DataBound" />
</td>
</tr>
</table>
<table>
<tr>
<td>
<br />
<asp:Button ID="btInsertOk" runat="server" Text="Add" CommandName="Insert" />
<asp:Button ID="btInsertCancel" runat="server" Text="Cancel" />
</td>
</tr>
</table>
</asp:Panel>
</EditItemTemplate>
提前谢谢。
更改代码隐藏中的选定值时,事件似乎不会触发。仅当用户通过在下拉列表中选择新值来更改值时,才会触发它。
您可以做的是将代码从事件中移出到单独的方法中,并从事件中调用该方法。当用户通过 UI 进行更改时,您的事件仍将触发。
protected void ddChild_SelectedIndexChanged(object sender, EventArgs e)
{
ImportantStuff();
}
public void ImportantStuff()
{
// everything that was in the SelectedIndexChanged event
}
然后在按钮单击事件中,存储旧的SelectedIndex
值,进行更改,并将其与新的SelectedIndex
值进行比较。如果它们不同,则所选索引已更改,您可以调用上述 SelectedIndexChanged
事件调用的相同方法:
protected void btnMyBUtton_Click(object sender, EventArgs args)
{
pnlUserControl_ModalPopupExtender.Show();
if (ddParent.SelectedIndex > 0)
{
DropDownList dd = ucMyControl.FindControlRecursive("ddChild") as DropDownList;
var oldIndex = dd.SelectedIndex;
dd.SelectedValue = ddParent.SelectedValue;
var newIndex = dd.SelectedIndex;
if (oldIndex != newIndex) // selected index changed
ImportantStuff();
}
}
正如 Sam 所指出的,ImportantStuff()
方法应该在 UserControl 中是公共的,因此您可以从 UserControl 所在的页面访问它。
更好的是,假设"重要内容"不需要访问 UserControl 中的其他控件,您可以将该代码移动到单独的类中,然后从两个位置调用它,而无需 Page 调用 UserControl 中的公共方法(您的代码保持更简洁,更少纠结(。
SelectedIndexChanged
事件有点令人困惑。根据MSDN
此方法的定义是
当从列表控件中选择的内容在帖子之间更改时发生 到服务器。
因此,在这种情况下,即使您未从 DropDownList 中选择任何内容,此事件也会在下一次回发中触发(因为没有AutoPostback
(。这是因为所选索引在回发之间发生了更改。不确定这是否是一个错误。我做了一点测试,这是真的。如果我错了,请纠正我。我今天学到了一些新东西:)
溶液
问题的解决方案是@GrantWinney建议的。将 SelectedIndexChanged
事件中的常见功能提取到公共事件中,并在下一行之后调用该方法。
dd.SelectedValue = ddParent.SelectedValue;
如果您的 ddChild 控件采用相同的方法,您可以通过按如下方式调用它来调用它SelectedIndexChanged
事件
ddChild_SelectedIndexChanged(sender, args);
我假设您正在ajax弹出窗口中显示您的用户控件。您可以尝试像这样弹出您的用户控件:
<asp:Panel ID="pseudopopup" runat="server" visible="false">
<table style="position: fixed; z-index: 1; left: 0px; top: 0px" border="0" width="100%" height="100%">
<tr>
<td valign="top" align="center" >
<div style="margin:top:60px; width:600px" class="shadow"
<ascx:WebUserControl ID="mycontrol" runat="server" />
</div>
</td>
</tr>
</table>
</asp:Panel>
在代码隐藏中:
protected void btnMyBUtton_Click(object sender, EventArgs args)
pseudopopup.Visible = true;