2010-02-04 73 views
0

我有一個用於UpdatePanel內部的UserControl。ModalPopup/UpdatePanel中的DropDownList間歇性地不觸發SelectedIndexChanged

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

ProtocolCycleNumber和ProtocolCycleID只是整數。沒有任何可能干擾javascript的機會。

+0

公平的解決辦法AutoPostback=true ...當然這將是更好,如果「的SelectedIndexChanged」只是工作:) – anthares 2010-02-04 23:31:59

回答

1

這種解決方案很醜,但它的工作原理,在這一點上,我需要得到它的工作,繼續前進。

簡而言之,我添加了一個不可見的按鈕,然後使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的問題,這是因爲我需要在我的ListIems中有重複的值 - 文本不同,但值有時是相同的。

顯然,當你這樣做時,ViewState會修復恢復狀態的工作,並選擇它找到的第一個匹配值。所以我只是讓我的價值更加細緻一點,現在工作得很好。

2

這是一個普遍的問題,你可以檢查出這個線程: http://forums.asp.net/t/1103779.aspx

有一些局部的解決方案,如果他們中的一些適合您的需要。

+0

@anthares:謝謝,這讓我在正確的軌道上。或者至少在/ a /軌道上。我不確定我的解決方案是否是最美麗的解決方案。 – 2010-02-04 16:29:10

1

我有同樣的問題,我解決它通過添加modalpop.show()

例如

在設計文件中

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