Friday, September 01, 2006

Datagrids ruined my life!

I've been trying to setup an ASP.NET datagrid with dropdowns for data editing and as you will see from this link it took much longer than perhaps it should have done. The main problem being pre-selecting values. There seems to be a lot of conflicting advice and opinions on the best way to do this sort of thing. What I intend to do here is give a fairly generic solution that worked for me in this particular case.


  • Setup your datagrid as normal. The columns you want drop downs for need to be made to template columns. The ones you don't want to be editable should be marked read only.

  • Add an edit column as per normal

  • In the template columns, put in your desired objects and layout and assign properties as per normal. This is what will appear in that column when the user hits edit and can contain pretty much any html or asp that you like.

  • In my page behind code I added a new subroutine to bind data to whatever you want in your template(s) that you setup above. Essentially this code is the same as that you would use for binding data to the datagrid itself. (Presumably this can also be done by dragging and dropping the appropriate dataadapters etc. when you are editing the template but I prefer to do it in code.) The difference is that you need to be able to reference the objects that you have put into the template. This code needs to be called from the ItemDataBound event handler (where incidentally you can apply conditional formatting to cells but that is for another time). One of the parameters passed to this event handler is
    e As System.Web.UI.WebControls.DataGridItemEventArgs You can use this to find the controls you have put into your template. In my case I had a drop down in the template and so the declaration
    Dim MyDropDown As DropDownList = CType(e.Item.FindControl("MyTemplateDropDown"), DropDownList) generates a reference to the dropdown control which can now just be treated as a normal drop down object.
  • To pre-select an existing value is now easy as it largely uses the code from the Microsoft site -
    If e.Item.ItemType = ListItemType.EditItem Then
    BindDGRow(e) ' This is the call that binds the datarow as described above
    Dim drv As DataRowView = CType(e.Item.DataItem, DataRowView)
    Dim currentValueInDataGrid As String = CType(drv("MyColumnNameInUnderlyingData"), String)
    MyDropDown.SelectedIndex = MyDropDown.Items.IndexOf(MyDropDown.Items.FindByValue(currentValueInDataGrid))

Easy!

No comments: