繁体   English   中英

SelectedIndexChanged事件未在子控件中触发

[英]SelectedIndexChanged event not firing in child control

我有一个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>

提前致谢。

似乎在隐藏代码中更改所选值时不会触发该事件。 仅当用户通过在下拉菜单中选择新值来更改值时才会触发。

您可以做的是将代码从事件中移出到单独的方法中,然后从事件中调用该方法。 当用户通过用户界面进行更改时,您的事件仍会触发。

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 ,此方法的定义是

当列表控件中的选择在服务器的帖子之间更改时发生。

因此,在这种情况下(因为没有AutoPostback ),即使没有从DropDownList中选择任何内容,此事件也会在下一次回发触发 这是因为所选索引在回发之间已更改。 不确定这是否是错误。 我做了一点测试,这是事实。 如果我错了纠正我。 我今天学到了一些新东西:)

问题的解决方案是@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;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM