ic3man7019
ic3man7019

Reputation: 711

How I can access a control inside an ItemTemplate and connect it to a datasource by the time it is initialized?

I know that there are similar questions to this one out there, but I can't seem to find any that address my issue.

I have a GridView that is populated with data from my database. The user has the option to delete or edit this data, a pretty standard operation. To insert data into the GridView, the user fills out a form and presses the submit button. In the form, there are three textboxes and a DropDownList. As you may expect, this means that, inside the GridView in edit mode, there are three textboxes and a DropDownList. My issue is this: When the user presses the Edit button, the application breaks. It says something to the effect of "myDropDownList cannot be loaded because the selected value is not in the list of items." Basically, the DropDownList inside the EditItemTemplate in the GridView is empty. I have tried to populate it the same way that I populate the other DropDownList (the one in the form), but it is not initialized until the GridView is put in edit mode. Here is the markup for the EditItemTemplate:

I have omitted some code for brevity.

<asp:TemplateField HeaderText="LocationCode" SortExpression="LocationCode">
    <EditItemTemplate>
        <asp:DropDownList ID="Ddl_EditLocCode" SelectedValue='<%# Bind("LocationCode") %>' runat="server"></asp:DropDownList>
        <asp:RequiredFieldValidator ID="rfvLocCode" runat="server" ErrorMessage="Location Code is a required field."
            ControlToValidate="Ddl_EditLocCode" ForeColor="Red"></asp:RequiredFieldValidator>
    </EditItemTemplate>
    <ItemTemplate>
        <asp:Label runat="server" Text='<%# Bind("LocationCode") %>' ID="Label5"></asp:Label>
    </ItemTemplate>
</asp:TemplateField>

Here is the code I have written to populate the DropDownList inside the EditItemTemplate:

Note that this is the RowDataBound event handler.

Private Sub Gv_Assignments_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles Gv_Assignments.RowDataBound

    If e.Row.RowType = DataControlRowType.DataRow Then
        If DataControlRowState.Edit Then
            Dim editLocCodeDdl As DropDownList = DirectCast(e.Row.FindControl("Ddl_EditLocCode"), DropDownList)
            CreateDataSourceForEditDdl(editLocCodeDdl)
        End If
    End If

End Sub

Protected Sub CreateDataSourceForEditDdl(editLocCodeDdl As DropDownList)
    Try
        Dim conn As New Connection
        Dim DataReader As SqlDataReader
        Dim listItem As New ListItem
        Using conn.Conn
            conn.Conn.Open()
            Using cmd As New SqlCommand
                With cmd
                    .Connection = conn.Conn
                    .CommandType = CommandType.Text
                    .CommandText = "SELECT [location_code], [loc_name] FROM [myTable] ORDER BY [location_code]"
                End With
                DataReader = cmd.ExecuteReader()
                Dim locationCode As String
                Dim loc_name As String
                While DataReader.Read()
                    locationCode = DataReader.Item("location_code").ToString()
                    loc_name = DataReader.Item("loc_name").ToString()
                    editLocCodeDdl.Items.Add(New ListItem(locationCode & "-" & loc_name))
                End While
            End Using
        End Using
    Catch ex As Exception
    End Try
End Sub

Perhaps the RowDataBound event handler is not where I should be attempting to populate the edit mode DropDownList... I'm not sure. Any help is greatly appreciated.

Edit: RowUpdating Code

Here is the RowUpdating code:

Private Sub Gv_Assignments_RowUpdating(sender As Object, e As GridViewUpdateEventArgs) Handles Gv_Assignments.RowUpdating
        'change the lessonID to the appropriate ID based on the lesson name
        'get the lesson name, then set the label text in the lesson ID column to the correct ID by calling GetLessonID(lessonname)

        Dim lessonNameBox As DropDownList = DirectCast(Gv_Assignments.Rows(e.RowIndex).FindControl("ddlEditLessonName"), DropDownList)
        'Dim lessonIdLabel As Label = DirectCast(Gv_Assignments.Rows(e.RowIndex).FindControl("LblLessonID"), Label)
        'Dim ID As Integer = Integer.Parse(Gv_Assignments.Rows(e.RowIndex).Cells(1).Text)
        'lessonIdLabel.Text = GetLessonID(lessonNameBox.SelectedValue)

        Gv_Assignments.Rows(e.RowIndex).Cells(3).Text = GetLessonID(lessonNameBox.SelectedValue)
        'UpdateLessonID(lessonIdLabel.Text, ID)
    End Sub

As you can see, I am doing pretty much nothing in this function. I should add that I used the GridView's smart tag to assign a SqlDataSource to the GridView. Every other editable cell gets successfully updated when I edit it in edit mode. For some reason, when I removed this line: SelectedValue='<%# Bind("LocationCode") %>', the Ddl_EditLocCode successfully populated with the desired values, but it failed to update on the back end and front end when I edited it; in fact, it made the value Null. Any ideas?

Edit 2: The SqlDataSource

<asp:SqlDataSource ID="sds_GvAssignments" runat="server" ConnectionString='<%$ ConnectionStrings:DedicatedTerminal_devConnectionString %>' 
                    DeleteCommand="DELETE FROM [CreatedAssignments] WHERE [ID] = @ID" 
                    InsertCommand="INSERT INTO [CreatedAssignments] ([LessonName], [LessonID], [StartDate], [EndDate], [LocationCode], 
                    [DateAssigned]) VALUES (@LessonName, @LessonID, @StartDate, @EndDate, @LocationCode, @DateAssigned)" 
                    SelectCommand="SELECT [ID], [LessonName], [LessonID], [StartDate], [EndDate], [LocationCode], [DateAssigned] 
                    FROM [CreatedAssignments]" UpdateCommand="UPDATE [CreatedAssignments] SET [LessonName] = @LessonName, 
                    [LessonID] = @LessonID, [StartDate] = @StartDate, [EndDate] = @EndDate, [LocationCode] = @LocationCode, 
                    [DateAssigned] = @DateAssigned WHERE [ID] = @ID">
                    <DeleteParameters>
                        <asp:Parameter Name="ID" Type="Int32"></asp:Parameter>
                    </DeleteParameters>
                    <InsertParameters>
                        <asp:Parameter Name="LessonName" Type="String"></asp:Parameter>
                        <asp:Parameter Name="LessonID" Type="String"></asp:Parameter>
                        <asp:Parameter DbType="Date" Name="StartDate"></asp:Parameter>
                        <asp:Parameter DbType="Date" Name="EndDate"></asp:Parameter>
                        <asp:Parameter Name="LocationCode" Type="String"></asp:Parameter>
                        <asp:Parameter Name="DateAssigned" Type="DateTime"></asp:Parameter>
                    </InsertParameters>
                    <UpdateParameters>
                        <asp:Parameter Name="LessonName" Type="String"></asp:Parameter>
                        <asp:Parameter Name="LessonID" Type="String"></asp:Parameter>
                        <asp:Parameter DbType="Date" Name="StartDate"></asp:Parameter>
                        <asp:Parameter DbType="Date" Name="EndDate"></asp:Parameter>
                        <asp:Parameter Name="LocationCode" Type="String"></asp:Parameter>
                        <asp:Parameter Name="DateAssigned" Type="DateTime"></asp:Parameter>
                        <asp:Parameter Name="ID" Type="Int32"></asp:Parameter>
                    </UpdateParameters>
                </asp:SqlDataSource>

Upvotes: 0

Views: 116

Answers (1)

VDWWD
VDWWD

Reputation: 35554

The code to fill the DropDownList seems ok at first glance. First try removing SelectedValue='<%# Bind("LocationCode") %>'. The error means that the value of LocationCode does not exist in the ListItems of Ddl_EditLocCode.

And that would seem to make sense since you are adding a ListItem with a value of both the locationCode AND loc_name (New ListItem(locationCode & "-" & loc_name)), therefore only the value of LocationCode does not exist and throws the error.

The solution is to create a ListItem with both a Text and Value specified.

New ListItem(locationCode & "-" & loc_name, locationCode, true)

Upvotes: 1

Related Questions