代码之家  ›  专栏  ›  技术社区  ›  Brian MacKay

modalpopup/updatepanel中的DropDownList间歇性不激发SelectedIndexChanged

  •  0
  • Brian MacKay  · 技术社区  · 15 年前

    我有一个在更新面板内部使用的用户控件。

    UserControl是一个相当简单的表单,它通过ModalPopupExtender(也是UserControl的一部分)显示。有四个DropDownList,以及其他一些UI元素。

    四个DropDownlist中有三个的autopostback=“true”,其中selectedIndexChanged事件会在服务器上触发,并导致其他DropDownlist中的一些重新绑定。

    AutoPostback的三个DDL中有两个工作正常。其中一个,我刚补充说,是表现出一些奇怪的行为。

    假设我将五个项目绑定在它上面:1,2,3,4,5。我将selectedIndex设置为0,这使1成为所选项目。

    如果我选择5,然后选择1,继续来回切换,一切都会正常工作。发生回发并选择了DexChanged激发。每一次。

    如果我选择2或4,将发生回发,但SelectedIndexChanged不会触发。每一次。

    如果我选择3,会发生一些奇怪的事情,有时DDL的值会恢复为1。尽管断点似乎显示它没有重新绑定,也没有运行意外代码。我知道你的第一反应可能是我对重新绑定的代码没有运行是错误的,但是我已经盯着调试器好几个小时了,试图找出我的错误。很多断点。我不明白——这真的没那么复杂。

    但很明显我错过了什么。

    到目前为止,我已经花了四个小时的时间,我想我只是在磨磨蹭蹭。我可以用另一种观点。

    HTML(顺便说一下, DropProtocolCycleID 是问题控制):

    <asp:Panel ID="PanelPopupAssign" runat="server" Style="display:none; cursor: move; width:325px; background-color:Transparent;">
        <BlueUI:Panel runat="server" ID="PanelPatientProtocol" Width="500px" HeaderText="Assign Protocol">
        <table cellspacing="5">
            <tr>
                <td style="width:150px;"></td>
                <td style="width:50px;"></td>
                <td style="width:125px;"></td>
            </tr>
            <tr runat="server" id="TableRowCategory">
                <td align="right">Category:</td>
                <td colspan="2">
                    <asp:DropDownList runat="server" ID="DropProtocolCategories" CausesValidation="false" autopostback="true"/>
                </td>
            </tr>                        
            <tr>
                <td align="right">Protocol:</td>
                <td colspan="2">
                    <asp:DropDownList ID="DropProtocolID" runat="server" Enabled="false" CausesValidation="false" autopostback="true"/>
                    <asp:Label ID="LabelProtocolName_SetDate" runat="server" />
                </td>
            </tr>
    
            <tr>
                <td colspan="3">
    
                    <table style="margin-left: 120px">
    
                        <tr>
                            <td align="right">Cycle:</td>
                            <td><asp:DropDownList ID="DropProtocolCycleID" runat="server" autopostback="true" /></td>
                        </tr>
    
                        <tr>
                            <td align="right">Day:</td>
                            <td>
                                <asp:DropDownList ID="DropProtocolCycleDayID" runat="server" Enabled="false" />                                                 
                            </td>
                        </tr>
                    </table>
    
                </td>
            </tr>               
    
            <tr>
                <td align="right">Start Date:</td>
                <td colspan="2">
                    <table>
                        <tr>
                            <td>
                                <asp:Textbox ID="TextProtocolStartDate" runat="server" Width="65px" 
                                    BackColor="Transparent" BorderStyle="None" ReadOnly="True" Font-Size="11px" 
                                    ForeColor="#1C4071" Font-Names="Verdana" ValidationGroup="AssignProtocol" />                            
                            </td>
                            <td>
                                <img id="ImageProtocolStartDate" 
                                     alt="Calendar" 
                                     onclick="CalProtocolStartDate.show();" 
                                     class="calendar_button" 
                                     src="../../Images/Icons/btn_calendar.gif" 
                                     width="25" 
                                     height="22" />
                                <asp:RequiredFieldValidator ID="ValRequiredProtocolStartDate" runat="server" display="Dynamic" 
                                    ControlToValidate="TextProtocolStartDate" ErrorMessage="Protocol Start Date is required!" 
                                    InitialValue="(None)"
                                    Enabled="false" ValidationGroup="AssignProtocol">*</asp:RequiredFieldValidator>                               
                            </td>
                        </tr>
                    </table>
    
                </td>
            </tr>
        </table>
        <ComponentArt:Calendar runat="server" 
                id="CalProtocolStartDate" 
                AllowMonthSelection="false"
                AllowMultipleSelection="false"
                AllowWeekSelection="false"
                CalendarCssClass="calendar" 
                TitleCssClass="title" 
                ControlType="Calendar"
                DayCssClass="day" 
                DayHeaderCssClass="dayheader" 
                DayHoverCssClass="dayhover" 
                DayNameFormat="FirstTwoLetters"
                ImagesBaseUrl="~/Images/Calendar/"
                MonthCssClass="month"
                NextImageUrl="cal_nextMonth.gif"
                NextPrevCssClass="nextprev" 
                OtherMonthDayCssClass="othermonthday" 
                PopUp="Custom"
                PopUpExpandControlId="ImageProtocolStartDate"
                PrevImageUrl="cal_prevMonth.gif" 
                SelectedDate=""
                VisibleDate=""
                SelectedDayCssClass="selectedday" 
                SelectMonthCssClass="selector"
                SelectMonthText="¤" 
                SelectWeekCssClass="selector"
                SelectWeekText="»" 
                SwapDuration="300"
                SwapSlide="Linear" 
                AutoPostBackOnSelectionChanged="False" 
                PopUpCollapseDuration="0"
                ClientSideOnSelectionChanged="onCalProtocolStartDateChange"> 
              <ClientEvents>
                <Load EventHandler="Calendar1_onLoad" />
              </ClientEvents>
             </ComponentArt:Calendar>                        
        <br />
        <div style="text-align:center;">
            <asp:Button ID="ButtonSaveProtocol" runat="server" Text="Save" ValidationGroup="AssignProtocol" Enabled="false" />
            <asp:Button ID="ButtonCancel" runat="server" Text="Cancel" CausesValidation="false" />
        </div> 
        <br />
        </BlueUI:Panel>
    </asp:Panel> 
    
    <ajaxToolkit:ModalPopupExtender id="ModalPopupExtenderAssignProtocol" runat="server"
    popupcontrolid="PanelPopupAssign" popupdraghandlecontrolid="PanelPopupAssign" CancelControlID="ButtonCancel"
    targetcontrolid="ButtonAssignProtocol" BackgroundCssClass="modalBackground" RepositionMode="RepositionOnWindowResizeAndScroll" >
    </ajaxToolkit:ModalPopupExtender>  
    

    相关代码隐藏:

    Private Sub DropProtocolCycleID_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DropProtocolCycleID.SelectedIndexChanged
        Me.Show()
    
        Me.SetupDropProtocolCycleDayID()
    End Sub
    
    Public Sub Show()
        Me.ModalPopupExtenderAssignProtocol.Show()
    End Sub
    

    这是我绑定DropProtocolCycleID的代码,如果您感兴趣的话。它在DropProtocolid的SelectedIndexChanged事件中触发,实际工作可靠:

    Private Sub SetupDropProtocolCycleID()
        If Me.DropProtocolID.SelectedValue = Constants.NothingSelected Then
            Me.DropProtocolCycleID.Enabled = False
            Exit Sub
        Else
            Me.DropProtocolCycleID.Enabled = True
        End If
    
        Dim ProtocolID As Integer = Me.DropProtocolID.SelectedValue
        Dim ProtocolCycles As DataTable = ProtocolManager.GenerateCycleTable(ProtocolID)
    
        Me.DropProtocolCycleID.DataSource = ProtocolCycles
        Me.DropProtocolCycleID.DataTextField = "ProtocolCycleNumber"
        Me.DropProtocolCycleID.DataValueField = "ProtocolCycleID"
        Me.DropProtocolCycleID.DataBind()
    
        If DropProtocolCycleID.Items.Count > 0 Then
            Me.DropProtocolCycleID.SelectedIndex = 0
        End If
    End Sub
    

    原菌落数和原菌落数只是整数。没有任何可能干扰javascript的地方。

    3 回复  |  直到 8 年前
        1
  •  2
  •   anthares    15 年前

    这是一个常见的问题,您可以检查这个线程: http://forums.asp.net/t/1103779.aspx

    有一些部分解决方案,如果其中一些符合您的需要。

        2
  •  1
  •   Brian MacKay    10 年前

    这个解决方案是丑陋的,但它是有效的,在这一点上,我只需要让它工作并继续前进。

    简言之,我添加了一个不可见的按钮,然后让DropDownList的onChange事件在每次更改时用javascript单击该按钮。这解决了我们在这里处理的任何问题。

    我将此JS添加到页面:

    function IndexChanged() {
        document.getElementById("ctl00$MainContent$AssignProtocolControl$ButtonIndexChanged").click(); 
    }
    

    我把DropDownlist改为:

    <asp:DropDownList ID="DropProtocolCycleID" runat="server" onchange="IndexChanged();"  />
    

    我添加了隐形按钮:

    <asp:Button id="ButtonIndexChanged" Text="Index Changed" style="display: none;" OnClick="DropProtocolCycleID_SelectedIndexChanged" runat="server" />
    

    …这解决了问题。如果你发现更好的解决方案,请告诉我。

    哦,至于值有时会恢复为1的问题,是因为我需要在列表中有重复的值——文本是不同的,但值有时是相同的。

    显然,当您这样做时,viewstate会破坏恢复状态的工作,并选择找到的第一个匹配值。所以我只是把我的价值做得更详细了一点,它现在工作得很好。

        3
  •  1
  •   Akshay    8 年前

    我有同样的问题,我通过添加modalpop.show()解决了它。

    例如

    AutoPostback=true 在设计文件中

    protected void ddlCars_SelectedIndexChanged(object sender, EventArgs e)
        {
            //Do all your work here 
            mpEditCars.Show();
        }