简体   繁体   English

SelectedIndexChanged事件未在子控件中触发

[英]SelectedIndexChanged event not firing in child control

I have a asp.net control that references a user control(popup) when a button is pressed. 我有一个asp.net控件,当按下按钮时,该控件引用了一个用户控件(弹出窗口)。 When the button is pressed I find the drop down list in the popup user control and I set the selected value of it. 当按下按钮时,我会在弹出的用户控件中找到下拉列表,然后设置它的选定值。

  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;

        }
    }

In the popup user control I'm expecting the SelectedIndexChanged event to fire. 在弹出的用户控件中,我预计将触发SelectedIndexChanged事件。 However, it isn't. 但是,事实并非如此。 Any ideas why this would be the case? 任何想法为什么会是这种情况?

Markup for my child control(only relevant code) is below: 我的子控件的标记(仅相关代码)如下:

<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>

Thanks in advance. 提前致谢。

It seems the event doesn't fire when changing the selected value in the code-behind. 似乎在隐藏代码中更改所选值时不会触发该事件。 It only fires when the user changes the value by selecting a new value in the drop-down. 仅当用户通过在下拉菜单中选择新值来更改值时才会触发。

What you could do, is move your code out of the event into a separate method, and call that method from the event. 您可以做的是将代码从事件中移出到单独的方法中,然后从事件中调用该方法。 Your event will still fire when the user makes a change via the UI. 当用户通过用户界面进行更改时,您的事件仍会触发。

protected void ddChild_SelectedIndexChanged(object sender, EventArgs e)
{
    ImportantStuff();
}

public void ImportantStuff()
{
    // everything that was in the SelectedIndexChanged event
}

Then in your button click event, store the old SelectedIndex value, make the change, and compare it to the new SelectedIndex value. 然后在按钮单击事件中,存储旧的SelectedIndex值,进行更改,然后将其与新的SelectedIndex值进行比较。 If they're different, then the selected index has changed, and you can call the same method being called by the SelectedIndexChanged event above: 如果它们不同,则所选索引已更改,您可以调用上面的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();
    }
}

As Sam noted, the ImportantStuff() method should be public in the UserControl, so you can access it from the Page the UserControl is in. 正如Sam指出的那样, ImportantStuff()方法应该在UserControl中公开,因此您可以从UserControl所在的页面访问它。

Better yet, assuming the "important stuff" doesn't need to access other controls in the UserControl, you could move that code into a separate class, and then call it from both places without requiring a Page to call public methods in the UserControl (your code stays a little bit cleaner, and less tangled up). 更好的是,假设“重要的东西”不需要访问UserControl中的其他控件,则可以将该代码移到一个单独的类中,然后从两个地方调用它,而无需Page来调用UserControl中的公共方法(您的代码会更加整洁,并且不会纠结在一起)。

SelectedIndexChanged event is bit confusing. SelectedIndexChanged事件有点令人困惑。 According to MSDN the definition for this method is 根据MSDN ,此方法的定义是

Occurs when the selection from the list control changes between posts to the server. 当列表控件中的选择在服务器的帖子之间更改时发生。

So, this event fires in the next postback in this case (since there's no AutoPostback ) even if you don't select anything from the DropDownList. 因此,在这种情况下(因为没有AutoPostback ),即使没有从DropDownList中选择任何内容,此事件也会在下一次回发触发 This is because the selected index has changed between the postbacks. 这是因为所选索引在回发之间已更改。 Not sure whether this is a bug. 不确定这是否是错误。 I did little bit of testing and this is true. 我做了一点测试,这是事实。 Correct me if I'm wrong. 如果我错了纠正我。 I learnt something new today :) 我今天学到了一些新东西:)

Solution

The solution to the problem is what @GrantWinney suggested. 问题的解决方案是@GrantWinney建议的内容。 Extract the common functionality in the SelectedIndexChanged event into a public event and call that method just after the following line. SelectedIndexChanged事件中的通用功能提取到一个公共事件中,并在下一行之后调用该方法。

dd.SelectedValue = ddParent.SelectedValue;

If your ddChild control was in the same method you could just invoke it's SelectedIndexChanged event by calling it as follows 如果您的ddChild控件使用相同的方法,则可以按如下所示调用它的SelectedIndexChanged事件

ddChild_SelectedIndexChanged(sender, args);

I assume you are showing your user control in ajax popup. 我假设您正在ajax弹出窗口中显示用户控件。 You might try popping up your usercontrol like this: 您可以尝试像这样弹出用户控件:

<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>

In code behind: 在后面的代码中:

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