Home > OS >  Gridview Edit Mode - Drop down list does not show blank value
Gridview Edit Mode - Drop down list does not show blank value

Time:09-28

I have a drop down list 'Country', 'city' text box and an 'Add' button. The country drop down is NOT mandatory so I can just add a city without a country, adding an empty 'country' to the gridview works OK. the problem when I click on 'Edit' in the gridview it binds it to the first country in the list it does not just show a blank:

  <asp:DropDownList ID="DDLCountry" runat="server" AutoPostBack="true" AppendDataBoundItems="true" OnSelectedIndexChanged="DDLCountry_SelectedIndexChanged" InitialValue="">
 <asp:ListItem Text="------------------------ Select ------------------------" Value="" />
 </asp:DropDownList>
                                    
  <asp:TextBox ID="txtCity" runat="server"></asp:TextBox>

 <asp:Button ID="btnNewLList" runat="server" OnClick="btnNewLList_Click" Text="Add new Country"/>
<asp:GridView ID="gvAddNewCountry" runat="server" AutoGenerateColumns="False" DataKeyNames="ID" OnRowCommand="gvAddNewCountry_RowCommand" OnRowDeleting="gvAddNewCountry_RowDeleting" OnRowDataBound="gvAddNewCountry_RowDataBound" OnRowUpdating="gvAddNewCountry_RowUpdating" OnRowEditing="gvAddNewCountry_RowEditing" OnRowCancelingEdit="gvAddNewCountry_RowCancelingEdit" ShowHeaderWhenEmpty="True">
             <EmptyDataTemplate>
                              No Data
              </EmptyDataTemplate>
                     <Columns>
             <asp:TemplateField HeaderText="Actions">
                    <ItemTemplate>
                                                
  <asp:Button ID="btnEdit" runat="server" Text="Edit"/>
              </ItemTemplate>
                    </asp:TemplateField>
                       <asp:CommandField ButtonType="Button" ShowEditButton="true" ShowCancelButton="true">
                                  
                     </asp:CommandField>
                                          
                <asp:TemplateField HeaderText="Country>
                  <ItemTemplate>
                        <asp:Label ID="lblCountry" runat="server"  Text='<% #Eval("Country") %>'></asp:Label>
                   </ItemTemplate>
                <EditItemTemplate>
                      <asp:DropDownList ID="DDCountry" runat="server" AppendDataBoundItems="True" AutoPostBack="false"></asp:DropDownList>
                 </EditItemTemplate>
               </asp:TemplateField>

Code behind:

 Protected Sub gvAddNewCountry_RowCommand(sender As Object, e As GridViewCommandEventArgs)
  

    If e.CommandName = "Edit" Then
        Dim rowCountryToEdit As Integer = e.CommandArgument

        Dim ddListCountry As DropDownList = (CType(gvAddNewCountry.Rows(CInt(e.CommandArgument)).FindControl("DDCountry"), DropDownList))

            ddListCountry.DataSource = (From x In Country Where x.Domain = "lCountry" Order By x.Description Select x).ToList()
            ddListCountry.DataTextField = "Description"
            ddListCountry.DataValueField = "ID"
            ddListCountry.DataBind()
     End If
End Sub
      

Thanks for your help X

CodePudding user response:

Ok, so when you have/want a ddl in a gv row?

We require TWO steps.

First step: Load up the list of choices for the dll

2nd step: set the ddl to the current row value, or blank (no choice) if null no value exists yet for the current row. This ALSO means we have to get/grab the current row value for the dll, and set the ddl to reflect this existing choice.

So, this is a two step process.

And the "event" we typical use for this is the row bind event. (all such controls from listview, gridview and more have this event).

Also, a VERY nice helper tip? During (but ONLY during) the data bind event, you have FULL USE of ALL columns from the data source - EVEN COLUMNS NOT in the gv!!!

I don't have a entity database first setup that you have, but lets load up a gv with a combo box:

So, our gv:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
    CssClass="table table-hover" Width="50%"
    DataKeyNames="ID">
    <Columns>
        <asp:BoundField DataField="FirstName" HeaderText="First Name" />
        <asp:BoundField DataField="LastName" HeaderText="First Name" />
        <asp:BoundField DataField="HotelName" HeaderText="Hotel Name" />
        <asp:BoundField DataField="City" HeaderText="City" />
        <asp:BoundField DataField="Description" HeaderText="Descripiton" />
        <asp:TemplateField HeaderText="Rating">
            <ItemTemplate>
                <asp:DropDownList ID="cboRating" runat="server"
                    DataTextField="Rating"
                    DataValueField="ID">
                </asp:DropDownList>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

And our code to fill is this:

Dim rstRating As New DataTable
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    If Not IsPostBack Then
        LoadGrid()
    End If
End Sub

Sub LoadGrid()
    ' get data for rating combo
    rstRating = MyRst("SELECT ID, Rating FROM tblRating ORDER BY ID")

    ' get data for grid
    GridView1.DataSource = MyRst("SELECT * FROM tblHotelsA ORDER BY HotelName")
    GridView1.DataBind()

End Sub


Public Function MyRst(strSQL As String) As DataTable

    Dim rstData As New DataTable
    Using conn As New SqlConnection(My.Settings.TEST4)
        Using cmdSQL As New SqlCommand(strSQL, conn)
            conn.Open()
            rstData.Load(cmdSQL.ExecuteReader)
        End Using
    End Using
    Return rstData
End Function

Note VERY carefull in above, I created a page wide (class wide) data table called rstRating. This will go out of scope after the data bind, but we ONLY need it to persit DURING the gv data bind operating (since for each row of the gv, we don't want to run that query over and over - we need this same pick list for the dll).

Ok, so now we see/get this:

enter image description here

The only part we need is to load up the dll, and set it for each row. We use the RowDataBound event.

So, code for that was this:

Protected Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound

    ' bind drop down for each row
    If e.Row.RowType = DataControlRowType.DataRow Then
        ' get combo
        Dim rDrop As DropDownList = e.Row.FindControl("cboRating")
        rDrop.DataSource = rstRating
        rDrop.DataBind()
        rDrop.Items.Insert(0, New ListItem("Please Select", "0"))

        ' now get current row vallue for rating.
        Dim gData As DataRowView = e.Row.DataItem
        If IsDBNull(gData("Rating")) = False Then
            rDrop.Text = gData("Rating")
        End If
    End If

End Sub

So, for each row, get the dll.

For for that row, load up with choices

And THEN for that row, set the ddl to the current row value (but check for null, and don't set - it will then show our "select" choice value.

  • Related