Sorry for the interruption. I'll finish describing the details of having cascading DropDownList controls in edit mode of a GridView control. (Part 1 here.) I'll follow up in another post with some additional thoughts about the overall approach I've been illustrating.
The next task is to refresh the dependent drop-down list when the user makes a new selection in the master list. The master list control has AutoPostBack set to true; the refresh happens on SelectedIndexChanged:
Protected Sub listManufacturers_SelectedIndexChanged(ByVal sender As Object, _
ByVal e As System.EventArgs)
Dim listManufacturers, listModels As DropDownList
Dim dsModelsByManufacturer As AccessDataSource
Dim currentRowInEdit As Integer = GridView1.EditIndex
listManufacturers = CType(sender, DropDownList)
listModels = CType(GridView1.Rows(currentRowInEdit).FindControl("listModels"), _
DropDownList)
dsModelsByManufacturer = CType(GridView1.Rows( _
(currentRowInEdit).FindControl("dsModelsByManufacturer"), AccessDataSource)
dsModelsByManufacturer.SelectParameters("manufacturerID").DefaultValue = _
listManufacturers.SelectedValue
listModels.DataBind()
End Sub
(Gad, I really do wish it were easier to split lines in VB.)
(Update 13 Apr 2007 I changed the line that gets a reference to the listManufacturers drop-down list --
Dyaneshwar pointed out that I don't need to use FindControl, because it's already passed as the sender
argument of the method.)
The code is similar to the code for populating the lists originally, and probably could be refactored so that you reuse the same code.
Finally, the update. When the user clicks the Update
button, we need to set the parameter values that will be passed to the data source control that performs the actual update. We can do this during the GridView control's RowUpdating event by setting values in the NewValues dictionary of the System.Web.UI.WebControls.GridViewUpdateEventArgs object:
Protected Sub GridView1_RowUpdating(ByVal sender As Object, ByVal e _
As System.Web.UI.WebControls.GridViewUpdateEventArgs)
Dim listManufacturers As DropDownList = _
CType(GridView1.Rows(e.RowIndex).FindControl("listManufacturers"), _
DropDownList)
Dim listModels As DropDownList = _
CType(GridView1.Rows(e.RowIndex).FindControl("listModels"), _
DropDownList)
e.NewValues("ManufacturerID") = listManufacturers.SelectedValue
e.NewValues("ModelID") = listModels.SelectedValue
End Sub
The differences from the FormView version have primarily to do with the fact that the GridView control is showing multiple rows; in the FormView control, you're looking at one row at a time. For example, in the SelectedIndexChanged handler, we have to grub around -- that is, use GridView1.EditIndex -- to determine what row to turn our attentions to. We have to do essentially the same in the RowUpdating handler.
The grid itself is bound to a kind of complicated query (in the dsCarsForSale
data source control). In this particular iteration of the example, I created the Cars.mdb as an uber-normalized set of tables. In the ItemTemplate (ie, normal display mode) of the grid, I want to display manufacturer name and model name. That required some inner joining. But that doesn't affect the updates, which care only about the various IDs.
I've posted an example page here, and the approximate source for it here, so you don't have to try to reconstruct it all from the examples above.
Like I said, I'll post a couple of further thoughts about this whole discussion of cascading lists in the future.