To create a usable dropdownlist in datagrid

legendgod

Regular
Joined
May 17, 2004
Messages
53
Location
Hong Kong
I have successful generate a dropdownlist inside a datagrid's template edit item. But I don't know why whatever I select in the dropdownlist, it return the result same as before (That means no change at all). I have already spent 3 days and night in it.... Thank you a lot.
Code:
 Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim DS As New DataSet
        If Not IsPostBack Then
            loadDStoSession()
        Else
            Response.Write("Old session")
        End If
        DS = Session("scheduleDS")
        BindGridtoSource()
    End Sub

    Sub loadDStoSession()
        Response.Write("Session cleared!")
        Dim DS As New DataSet

        Dim schtable As New DataTable
        Dim StartDay, EndDay As Date
        StartDay = #7/6/2004#
        Dim ConnStr As String = ("Persist Security Info=False; Data Source=localhost; Initial Catalog=SSS; User ID=sa; Password=pwd;")
        Dim Conn As New SqlConnection
        Conn.ConnectionString = ConnStr
        Dim objAdapter As New SqlDataAdapter
        objAdapter.SelectCommand = New SqlCommand("Schedule3Query", Conn)
        objAdapter.SelectCommand.CommandType = CommandType.StoredProcedure
        objAdapter.SelectCommand.Parameters.Add(New SqlParameter("@StartDay", SqlDbType.SmallDateTime))

' The store procedure return 3 tables: 1st is a VIEW, 2nd is a TABLE carrying 
'the choice for the dropdownlist, 3rd is the TABLE which the View created 
'from.

        objAdapter.SelectCommand.Parameters("@StartDay").Value = StartDay
        Dim objCB As SqlCommandBuilder = New SqlCommandBuilder(objAdapter)
        objAdapter.Fill(DS)
        Dim DV As DataView = New DataView(DS.Tables(0))
        Session.Add("scheduleDS", DS)
        Session.Add("scheduleDV", DV)
    End Sub

    Sub BindGridtoSource()
        Dim DS As New DataSet

        DS = Session("scheduleDS")
        Dim DV As DataView = New DataView(DS.Tables(0))        editSchDG.DataSource = DV
        editSchDG.DataBind()
    End Sub

    Sub edit_ScheduleEditItem(ByVal sender As Object, ByVal e As DataGridCommandEventArgs)
        editSchDG.EditItemIndex = e.Item.ItemIndex
        BindGridtoSource()
    End Sub

    Sub cancel_ScheduleEditItem(ByVal sender As Object, ByVal e As DataGridCommandEventArgs)
        editSchDG.EditItemIndex = -1
        BindGridtoSource()
    End Sub

    Sub update_ScheduleEditItem(ByVal sender As Object, ByVal e As DataGridCommandEventArgs)
        Dim hNameDropList As New DropDownList
        Dim Note As TextBox
        Dim hId, i As Integer
        hNameDropList = e.Item.FindControl("hNameDropList")
        Note = e.Item.Cells(3).Controls(0)
        hId = hNameDropList.SelectedValue
        Dim schId As Integer = editSchDG.DataKeys(e.Item.ItemIndex)
        Response.Write("<BR>hId = " & hId)
        Response.Write("<BR>schId = " & schId)
        Response.Write("<BR>Note = " & Note.Text)
        Dim DS As New DataSet
        Dim Dt As New DataTable
        DS = Session("scheduleDS")
        Dt = DS.Tables(2)
        Dim DV As New DataView(Dt)
        DV.AllowEdit = True
        DV.AllowNew = True
        DV.AllowDelete = True

        With DV
            .RowFilter = "schId =" & schId
        End With
        For i = 0 To DV.Count - 1
            DV(i).Item("hId") = hId
        Next

        Session.Add("scheduleDV", DV)
        Session.Add("scheduleDS", DS)

        editSchDG.EditItemIndex = -1
        BindGridtoSource()
    End Sub

    Function GethNameList()
        Dim TempDataView As New DataView
        Dim DS As New DataSet
        Dim Dt As New DataTable
        DS = Session("scheduleDS")
        TempDataView = DS.Tables(1).DefaultView
        Return TempDataView
    End Function

    Function GethIdIndex(ByVal hId As Integer)
        Dim i As Integer
        Dim DS As DataSet
        DS = Session("scheduleDS")
        Dim Dt As New DataTable
        Dt = DS.Tables(1)
        For i = 0 To Dt.DefaultView.Count - 1
            If Dt.DefaultView(i).Item("hId") = hId Then
                Return i
            End If
        Next
        Return 0
    End Function
 
here is the html side

Here is the html side coding for you reference. Thank you very much. I have already search for some sample code on Internet. I still don't know what I have missed.
Code:
<asp:datagrid id="editSchDG" runat="server" DataKeyField="schId" AutoGenerateColumns="False" OnUpdateCommand="update_ScheduleEditItem"
				OnCancelCommand="cancel_ScheduleEditItem" OnEditCommand="edit_ScheduleEditItem">
				<Columns>
					<asp:BoundColumn DataField="schId" ReadOnly="True" HeaderText="Schedule ID"></asp:BoundColumn>
					<asp:BoundColumn DataField="cId" HeaderText="Client ID"></asp:BoundColumn>
					<asp:TemplateColumn HeaderText="Helper Name">
						<ItemTemplate>
							<asp:Label runat="server" text='<%# DataBinder.Eval(Container.DataItem,"hName") %>' ID="hNameLabel">
							</asp:Label>
						</ItemTemplate>
						<EditItemTemplate>
							<asp:DropDownList ID="hNameDropList" runat="server" DataSource="<%# GethNameList() %>" DataTextField="hName" DataValueField="hId" EnableViewState=True SelectedIndex='<%# GethIdIndex(DataBinder.Eval(Container.DataItem, "hId")) %>'>
							</asp:DropDownList>
						</EditItemTemplate>
					</asp:TemplateColumn>
					<asp:BoundColumn DataField="schNote" HeaderText="Note"></asp:BoundColumn>
					<asp:EditCommandColumn ButtonType="LinkButton" UpdateText="update" HeaderText="edit column" CancelText="cancel" EditText="edit"></asp:EditCommandColumn>
				</Columns>
			</asp:datagrid>
 
Maybe you want to look at this peace of code which work in my project.
I realy can't tell you what is missing from your code. I put an example
of one of my column in my datagrid. Maybe you can compare the codes..

PHP:
<asp:TemplateColumn HeaderText="Priority">
				<ItemStyle Font-Size="XX-Small"></ItemStyle>
				<ItemTemplate>
					<%# DataBinder.Eval(Container.DataItem,"Priority") %>
				</ItemTemplate>
				<EditItemTemplate>
					<asp:DropDownList id=dropdownlist1 datasource='<%# GetDataSet("Priority_Catalog","Name") %>' Runat="server" DataValueField="Name" DataTextField="Name" SelectedIndex='<%#GetSelectedIndex(Container.Dataitem("Priority"),"Priority_Catalog","Name") %>'>
					</asp:DropDownList>
				</EditItemTemplate>
			</asp:TemplateColumn>
 
Thank you for your reply, I see not much difference between your and my structure. May I see the code of "GetDataSet" and "GetSelectedIndex"?
 
legendgod said:
Thank you for your reply, I see not much difference between your and my structure. May I see the code of "GetDataSet" and "GetSelectedIndex"?

GetDataSet:
Code:
'=======================================================================
    ' This function is called after the user clicked the Edit buttonlink
    ' It gets the table and column name and return a datatable which contain
    ' 1 column with all its values. this coulmn will be the items of a 
    ' dropdown list in the datagrid while in edit mode.
    '========================================================================
    Public Function GetDataSet(ByVal table As String, ByVal col As String) As DataTable
        Dim strConn As String = "data source=HERZLIANS1;initial catalog=TestManager;persist security info=False;SE" & _
        "RVER=HERZLIANS1;user ID=Ido;Password=WTM70000;"

        Dim objConn As New SqlConnection(strConn)
        Dim strSQL As String
        If table = "AssignTo_Catalog" Then
            strSQL = "SELECT Employee_Catalog.Name, Employee_Catalog.ID FROM Employee_Catalog INNER JOIN EmployeeGroup_Catalog ON Employee_Catalog.EmployeeGroup = EmployeeGroup_Catalog.ID WHERE (EmployeeGroup_Catalog.GroupType = 'QA')"
        Else
            strSQL = "SELECT " & Trim(col) & " From " & Trim(table)
        End If
        Dim mydataadapter As SqlDataAdapter
        mydataadapter = New SqlDataAdapter(strSQL, objConn)

        'fill the dataset
        objConn.Open()
        mydataadapter.Fill(ddldataset, table) 'table
        objConn.Close()
        Return ddldataset.Tables(table) 'return the dataset
    End Function

GetSelectedIndex:
Code:
'=======================================================================
    ' This function is called after the user clicked the Edit buttonlink
    ' The purpose of this function is to display the current item of a 
    ' dropdown list while in edit mode (and not to disply the default first item)
    ' The function return the current selectedIndex
    '========================================================================
Public Function GetSelectedIndex(ByVal item As String, ByVal table As String, ByVal col As String) As Integer
        hTable(item) = table.Replace("_Catalog", Nothing)
        'loop through the dataset ddlDataSet
        Dim i As Integer
        Dim dt As DataTable = ddldataset.Tables(table)
        For i = 0 To dt.Rows.Count - 1
            If Trim(item) = Trim(dt.Rows(i)(col).ToString()) Then
                Return i
            End If
        Next
    End Function

I declared at the top of the page (as public) these variables:
Private ddldataset As DataSet = New DataSet()
Private hTable As New Hashtable()



Hope this help.
 
Thanks Ido for your kindly help. After several hours of testing, I believe I have made nothing wrong with building out the dropdownlist EXCEPT I cannot catch the new selection of user.

Let's say we have a dropdownlist with choices (A,B,C,D) and the oringinal value we dataset is A. I have write a function that whatever item I updated will have a "@@@" mark after it. E.g. A => A@@@

When the user click editcommand, the label A become a dropdownlist with A,B,C,D while A is highlighted. Then, user click D and then click the updatecommand. After then, the row I changed have update from A towards A@@@. That means the function completely cannot get the latest viewstate!

Also, the same result occur for all column and item using Textbox! The function completely cannot get the latest viewstate.

Any idea is helpful! Thank you!
 
If i understand - the problem you have is that after you click the update link
you donn't see changes yo made.

On the update function the work is relative simple.
You need to work here with both the datagrid and your dataset (or another object which hold your datagrid data).
On the datagrid you have to loop through all the columns of the edited row and update the dataset. Then all you left to do is to rebind your datagrid.
datagrid1.datasource = myDataset
datagrid1.databind.


Use e.Item.ItemIndex to get the edited row index in the datagrid.
Here is an example:


Code:
Dim ds As DataSet
ds = Session("SanityDataSet")
Dim i As Integer
Dim myDropDownList As New DropDownList()

[COLOR=YellowGreen][B]'loop through the datagrid columns of the edited row:[/B][/COLOR]
For i = 5 To n_DatagridColumns - 1
     If DataGrid1.Columns(i).Visible = True Then [B][COLOR=YellowGreen]'column is visible?[/COLOR][/B]      
       myDropDownList = CType(e.Item.FindControl ("DropDownList1") ,ropDownList)
        If Not myDropDownList Is Nothing Then [COLOR=YellowGreen][B]'dropdownlist1 found?[/B][/COLOR]
               If myDropDownList.SelectedIndex <> -1 Then
                   ds.Tables("Sanity").Rows(e.Item.ItemIndex)(i) = Trim 
                   (myDropDownList.SelectedItem.Value())
                                End If
                            Else   [B][COLOR=YellowGreen]'could be a text box.... ??[/COLOR][/B]
                                myTextBox = CType(e.Item.FindControl("txtMoreInformation"), TextBox)
                                ds.Tables("Sanity").Rows(e.Item.ItemIndex)("MoreInformation") = Trim(myTextBox.Text())
                                                           End If
                        End If
                    Next


[COLOR=YellowGreen][B]'now rebind the updated dataset to your datagrid:[/B][/COLOR]
datagrid1.datasource = ds
datagrid1.databind
 
Last edited:
Ido, thanks for your idea. I have spent some more hours to try and finally figure out the bug.... I rebind the datagrid every time page_load. Therefore everytime the dropdownlist changed, and submit, the datagrid bind old data again....
It's really stupid =P
Thank you for you help anyway!
 
Back
Top