首页 文章

ModalPopup / UpdatePanel中的DropDownList间歇性地不会触发SelectedIndexChanged

提问于
浏览
0

我有一个在UpdatePanel内部使用的UserControl .

UserControl是一个相当简单的表单,它通过ModalPopupExtender(也是UserControl的一部分)出现 . 有四个DropDownLists,以及一些其他UI元素 .

四个DropDownLists中有三个具有AutoPostBack =“true”,其中的SelectedIndexChanged事件在服务器上触发并导致其他一些DropDownLists重新绑定 .

AutoPostBack正在运行的三个DDL中的两个正常工作 . 其中一个,我刚刚添加,显示出一些奇怪的行为 .

假设我将五个项目绑定到它:1,2,3,4,5 . 我将SelectedIndex设置为0,这使得所选项目为1 .

如果我选择5然后选择1并继续来回切换,一切正常 . 发生回发并触发SelectedIndexChanged . 每次 .

如果我选择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>                        
    
<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>
</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

ProtocolCycleNumber和ProtocolCycleID只是整数 . 没有任何可能干扰javascript的机会 .

3 回答

  • 1

    这是一个常见的问题,你可以查看这个帖子:http://forums.asp.net/t/1103779.aspx

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

  • 2

    这个解决方案很丑陋,但它确实有效,此时我需要让它工作并继续前进 .

    简而言之,我添加了一个隐形按钮,然后使用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" />
    

    ......这解决了这个问题 . 如果您发现更好的解决方案,请告诉我 .

    哦,至于 Value 有时会被恢复为1的问题,这是因为我需要在ListIems中有重复的值 - 文本各不相同,但值有时相同 .

    显然,当你这样做时,ViewState会破坏恢复状态的工作并选择它找到的第一个匹配值 . 所以我只是让我的 Value 更加精细,现在工作正常 .

  • 1

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

    例如

    AutoPostback=true 在设计文件中

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

相关问题