SelectedIndexChanged事件未在子控件中触发

时间:2014-12-02 01:46:30

标签: c# asp.net drop-down-menu

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

提前致谢。

3 个答案:

答案 0 :(得分:0)

在代码隐藏中更改选定值时,似乎事件不会触发。它仅在用户通过在下拉列表中选择新值来更改值时触发。

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

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(你的代码保持一点点清洁,不那么纠结)。

答案 1 :(得分:0)

SelectedIndexChanged事件有点令人困惑。根据{{​​1}},此方法的定义是

  

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

因此,即使您没有从DropDownList中选择任何内容,此事件也会在下一次回发中触发(因为没有MSDN)。这是因为所选索引在回发之间发生了变化。不确定这是不是一个bug。我做了一些测试,这是事实。如果我错了,请纠正我。我今天学到了一些东西:)

<强>解决方案

问题的解决方案是@GrantWinney所建议的。将AutoPostback事件中的常用功能提取到公共事件中,并在以下行之后调用该方法。

SelectedIndexChanged

如果您的ddChild控件采用相同的方法,您可以通过调用它来调用它的dd.SelectedValue = ddParent.SelectedValue; 事件,如下所示

SelectedIndexChanged

答案 2 :(得分:0)

我假设你在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;