none
有關由DetailsView裡的ddl和HeaderText互動的問題 RRS feed

  • 問題

  • 各位大大好

    我用findcontrol設定DetailsView裡的某個ddl(1,2),用它的selectedvalue改變這個DetailsView的HeaderText

     

     

    If DetailsView3.CurrentMode = DetailsViewMode.Edit Then

                Dim ddl_C = CType(DetailsView3.FindControl("DropDownList1"), DropDownList)

                Dim aaaa As String

     

                If ddl_C.SelectedValue = 1 Then

                    aaaa = "bb"

                 Else

                    aaaa = "cc"

                End If

                DetailsView3.Fields(6).HeaderText = aaaa

    End If

    在執行時,會發生一個問題,就是當在操作ddl時,由1變成2沒問題,再由2變成1也沒問題,但是當再次由1變成2時,在headertext變完後,ddl會自動跳回1..

    不知各位大大是否曾經做過類似的設定,是否我少設定是什麼呢?

    敬請各位幫忙指教,謝謝

     


    蟲蟲左眼, 初學生, 謝謝您的指教
    2011年7月31日 上午 11:23

解答

  • Hi:

    我想會不會是因為該DropDownList有設AutoPostBack=True的關係

    導致每次下拉點選觸發SelectedIndexChanged事件後又再觸發DetailsView的DataBind事件,而DetailsView的DataBind事件所做的動作就是把畫面再洗回原本的畫面

    所以您要不要試試看下拉選單觸發SelectedIndexChanged事件時,把SelectedValue存到ViewState,然後DetailsView的DataBind事件去判斷

    有該ViewState時,下拉選單的值就選在該值,沒有該ViewState時,下拉選單就選在第一筆

    講得很抽象

    以下是具體實現(可能需要視您自己的需求更動程式碼名稱)

     <asp:SqlDataSource runat="server" ID="sds_Categories" 
     ConnectionString="<%$ ConnectionStrings:ConnectionString %>" 
     DeleteCommand="DELETE FROM [Categories] WHERE [CategoryID] = @CategoryID" 
     InsertCommand="INSERT INTO [Categories] ([CategoryName], [Description]) VALUES (@CategoryName, @Description)" 
     SelectCommand="SELECT [CategoryName], [CategoryID], [Description] FROM [Categories]" 
     UpdateCommand="UPDATE [Categories] SET [CategoryName] = @CategoryName, [Description] = @Description WHERE [CategoryID] = @CategoryID" >
     <DeleteParameters>
      <asp:Parameter Name="CategoryID" Type="Int32" />
     </DeleteParameters>
     <InsertParameters>
      <asp:Parameter Name="CategoryName" Type="String" />
      <asp:Parameter Name="Description" Type="String" />
     </InsertParameters>
     <UpdateParameters>
      <asp:Parameter Name="CategoryName" Type="String" />
      <asp:Parameter Name="Description" Type="String" />
      <asp:Parameter Name="CategoryID" Type="Int32" />
     </UpdateParameters>
     </asp:SqlDataSource>
     <br />
    
     <asp:DetailsView ID="DetailsView1" runat="server" Height="50px" Width="125px" 
     AutoGenerateRows="False" DataKeyNames="CategoryID" 
     DataSourceID="sds_Categories">
     <Fields>
      <asp:BoundField DataField="CategoryName" HeaderText="CategoryName" 
      SortExpression="CategoryName" />
      <asp:BoundField DataField="CategoryID" HeaderText="CategoryID" 
      InsertVisible="False" ReadOnly="True" SortExpression="CategoryID" />
      <asp:BoundField DataField="Description" HeaderText="Description" 
      SortExpression="Description" />
      <asp:TemplateField HeaderText="第一個下拉選單">
      <EditItemTemplate>
       <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true"
       onselectedindexchanged="DropDownList1_SelectedIndexChanged">
       <asp:ListItem Text="0" Value="0" />
       <asp:ListItem Text="1" Value="1" />
       </asp:DropDownList>
      </EditItemTemplate>
      </asp:TemplateField>
      <asp:TemplateField HeaderText="第二個下拉選單">
      <EditItemTemplate>
       <asp:DropDownList ID="DropDownList2" runat="server">
       </asp:DropDownList>
      </EditItemTemplate>
      </asp:TemplateField>
      <asp:CommandField ShowEditButton="True" ShowInsertButton="True" />
     </Fields>
     </asp:DetailsView>
    

     

     Protected Sub DetailsView1_DataBound(sender As Object, e As System.EventArgs) Handles DetailsView1.DataBound
     If DetailsView1.CurrentMode = DetailsViewMode.Edit Then
      Dim DropDownList1 = CType(DetailsView1.FindControl("DropDownList1"), DropDownList)
    
    
      If ViewState("ddlValue") IsNot Nothing Then 'ViewState有值,表示為剛才SelectedIndexChanged事件所塞的值
      DropDownList1.SelectedValue = CType(ViewState("ddlValue"), String)
      Else
       'ViewState無值,表示為第一次進來編輯模式
      DropDownList1.SelectedIndex = 0
    
      End If
    
     End If
    
     End Sub
    
    
     Protected Sub DropDownList1_SelectedIndexChanged(sender As Object, e As System.EventArgs)
    
     If DetailsView1.CurrentMode = DetailsViewMode.Edit Then
    
      Dim DropDownList1 = CType(DetailsView1.FindControl("DropDownList1"), DropDownList)
      Dim aaaa As String
    
    
      If (CType(DropDownList1.SelectedValue, Integer) = 1) Then
    
      aaaa = "bb"
    
      Else
    
      aaaa = "cc"
    
      End If
    
      DetailsView1.Fields(0).HeaderText = aaaa
    
    
      ViewState("ddlValue") = DropDownList1.SelectedValue
    
    
    
     End If
    
     End Sub
    

    Shadowと愉快なコード達
    Please correct me if my concept is wrong

    • 已標示為解答 蟲蟲左眼 2011年7月31日 下午 01:37
    2011年7月31日 上午 11:51

所有回覆

  • Hi:

    我想會不會是因為該DropDownList有設AutoPostBack=True的關係

    導致每次下拉點選觸發SelectedIndexChanged事件後又再觸發DetailsView的DataBind事件,而DetailsView的DataBind事件所做的動作就是把畫面再洗回原本的畫面

    所以您要不要試試看下拉選單觸發SelectedIndexChanged事件時,把SelectedValue存到ViewState,然後DetailsView的DataBind事件去判斷

    有該ViewState時,下拉選單的值就選在該值,沒有該ViewState時,下拉選單就選在第一筆

    講得很抽象

    以下是具體實現(可能需要視您自己的需求更動程式碼名稱)

     <asp:SqlDataSource runat="server" ID="sds_Categories" 
     ConnectionString="<%$ ConnectionStrings:ConnectionString %>" 
     DeleteCommand="DELETE FROM [Categories] WHERE [CategoryID] = @CategoryID" 
     InsertCommand="INSERT INTO [Categories] ([CategoryName], [Description]) VALUES (@CategoryName, @Description)" 
     SelectCommand="SELECT [CategoryName], [CategoryID], [Description] FROM [Categories]" 
     UpdateCommand="UPDATE [Categories] SET [CategoryName] = @CategoryName, [Description] = @Description WHERE [CategoryID] = @CategoryID" >
     <DeleteParameters>
      <asp:Parameter Name="CategoryID" Type="Int32" />
     </DeleteParameters>
     <InsertParameters>
      <asp:Parameter Name="CategoryName" Type="String" />
      <asp:Parameter Name="Description" Type="String" />
     </InsertParameters>
     <UpdateParameters>
      <asp:Parameter Name="CategoryName" Type="String" />
      <asp:Parameter Name="Description" Type="String" />
      <asp:Parameter Name="CategoryID" Type="Int32" />
     </UpdateParameters>
     </asp:SqlDataSource>
     <br />
    
     <asp:DetailsView ID="DetailsView1" runat="server" Height="50px" Width="125px" 
     AutoGenerateRows="False" DataKeyNames="CategoryID" 
     DataSourceID="sds_Categories">
     <Fields>
      <asp:BoundField DataField="CategoryName" HeaderText="CategoryName" 
      SortExpression="CategoryName" />
      <asp:BoundField DataField="CategoryID" HeaderText="CategoryID" 
      InsertVisible="False" ReadOnly="True" SortExpression="CategoryID" />
      <asp:BoundField DataField="Description" HeaderText="Description" 
      SortExpression="Description" />
      <asp:TemplateField HeaderText="第一個下拉選單">
      <EditItemTemplate>
       <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true"
       onselectedindexchanged="DropDownList1_SelectedIndexChanged">
       <asp:ListItem Text="0" Value="0" />
       <asp:ListItem Text="1" Value="1" />
       </asp:DropDownList>
      </EditItemTemplate>
      </asp:TemplateField>
      <asp:TemplateField HeaderText="第二個下拉選單">
      <EditItemTemplate>
       <asp:DropDownList ID="DropDownList2" runat="server">
       </asp:DropDownList>
      </EditItemTemplate>
      </asp:TemplateField>
      <asp:CommandField ShowEditButton="True" ShowInsertButton="True" />
     </Fields>
     </asp:DetailsView>
    

     

     Protected Sub DetailsView1_DataBound(sender As Object, e As System.EventArgs) Handles DetailsView1.DataBound
     If DetailsView1.CurrentMode = DetailsViewMode.Edit Then
      Dim DropDownList1 = CType(DetailsView1.FindControl("DropDownList1"), DropDownList)
    
    
      If ViewState("ddlValue") IsNot Nothing Then 'ViewState有值,表示為剛才SelectedIndexChanged事件所塞的值
      DropDownList1.SelectedValue = CType(ViewState("ddlValue"), String)
      Else
       'ViewState無值,表示為第一次進來編輯模式
      DropDownList1.SelectedIndex = 0
    
      End If
    
     End If
    
     End Sub
    
    
     Protected Sub DropDownList1_SelectedIndexChanged(sender As Object, e As System.EventArgs)
    
     If DetailsView1.CurrentMode = DetailsViewMode.Edit Then
    
      Dim DropDownList1 = CType(DetailsView1.FindControl("DropDownList1"), DropDownList)
      Dim aaaa As String
    
    
      If (CType(DropDownList1.SelectedValue, Integer) = 1) Then
    
      aaaa = "bb"
    
      Else
    
      aaaa = "cc"
    
      End If
    
      DetailsView1.Fields(0).HeaderText = aaaa
    
    
      ViewState("ddlValue") = DropDownList1.SelectedValue
    
    
    
     End If
    
     End Sub
    

    Shadowと愉快なコード達
    Please correct me if my concept is wrong

    • 已標示為解答 蟲蟲左眼 2011年7月31日 下午 01:37
    2011年7月31日 上午 11:51
  • 謝謝shadow,您的看法是對的,而且用您的方法,讓DetailsView被觸發DataBound時,在DataBound裡再把選取的ddl的值再拉回來,真是個好方法。

    在這裡用viewstate而不用session,是不是因為viewstate在執行完就變回nothing?

    再次謝謝大大的幫忙,叩謝


    蟲蟲左眼, 初學生, 謝謝您的指教
    2011年7月31日 下午 01:37
  • 謝謝shadow,您的看法是對的,而且用您的方法,讓DetailsView被觸發DataBound時,在DataBound裡再把選取的ddl的值再拉回來,真是個好方法。

    在這裡用viewstate而不用session,是不是因為viewstate在執行完就變回nothing?

    再次謝謝大大的幫忙,叩謝


    蟲蟲左眼, 初學生, 謝謝您的指教

    問這問題,代表之前的reference,您沒有完全瞭解ViewState與Session使用上的差異。

    請參考:

    暫存資訊 in ASP.NET


    常用資源參考:
    小弟的blog: In 91,wiki: my wiki
    2011年7月31日 下午 01:44
    版主
  • Hi:

    這種場合我會想用ViewState的原因

    主要是因為都是在Postback之間操作,而且要儲存的資料並不會很大,所以使用ViewState

    使用Session就怕萬一IE另開一個頁籤,然後進到初始頁面>再進到DetailsView的編輯模式,這時候Session的值應該會被上次的結果干擾

     

    然後ViewState和Session的比較,讓小弟借用一下版主的文章:

    http://www.dotblogs.com.tw/hatelove/archive/2009/06/28/viewstate-session-cache-cookies-application-of-user-state.aspx


    Shadowと愉快なコード達
    Please correct me if my concept is wrong

    2011年7月31日 下午 01:49
  • 謝謝shadow和91大大的指點

    91大大有關viewstate, session, cookies, application state比較的大作,是相檔重要的參考文件

    感謝兩位的幫忙,謝謝


    蟲蟲左眼, 初學生, 謝謝您的指教
    2011年7月31日 下午 02:03