1

I have a GridView with a DropDownList. The DropDownList items need to be set into the code behind. I checked online code samples and it looks I am supposed to code it this way:

<asp:GridView ID="DG_Table" runat="server" style="z-index: 1;autogeneratecolumns="False" 
onrowcommand="DG_Table_RowCommand"  
onrowdatabound="onrowdatabound">  

   <Columns>
     <asp:TemplateField HeaderText="Name" >
      <ItemTemplate>
         <asp:DropDownList ID="Name" runat="server" Text='<%# Bind("Name") %>'></asp:TextBox>
      </ItemTemplate>
   <asp:TemplateField HeaderText="field1" >
      <ItemTemplate>
        <asp:TextBox ID="field1" runat="server" Text='<%# Eval("FieldValue") %>'></asp:TextBox>
     </ItemTemplate>
 </Columns>
 </asp:GridView>

Into code behind:

public void onrowdatabound(object sender, GridViewRowEventArgs e)
        {

            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                //check if is in edit mode
                if ((e.Row.RowState & DataControlRowState.Edit) > 0)
                {

                    DropDownList dropdownlist = (DropDownList)e.Row.FindControl("Name");
                    dropdownlist.DataSource = new List<string>() { "Pete", "Jack", "Steve", "Mike", "Rob", "Jim", "Eric" };
                    dropdownlist.DataBind();
                }
            }
        }

When debugging, I can see that the debugger enters onrowdatabound. At this time, e.Row.RowType == DataControlRowType.Header

This is probably normal at this stage. So the debugger exits the method. I would expect the debugger to enter onrowdatabound again when attempting to add lines to the DataGrid. Somehow it does not, so the Datasource is never set and the code later on tries to add a value to the dropdownlist which does not belong to the dropdownlist.Items, causing an execution error:

Additional information: 'Name' has a SelectedValue which is invalid because it does not exist in the list of items.

(which is logical since the dropdownlist.datasource has never been set.

When DG_Table.DataBind() is called, there are 3 rows:

protected void B_Fill_Fennec_Click(object sender, EventArgs e)
        {
            List<fennec> list_fennec = new List<fennec>() { new fennec("Pete", "dev"), new fennec("Jack", "butcher"), new fennec("Steve", "wood chopper"), };

            GridView1.DataSource = list_fennec.Select(x => new { Name = x.Name, FieldValue = x.Occupation });
            GridView1.DataBind();
        }

Any help appreciated.

2
  • Is this a typo? or this is how it is coded? style="z-index: 1;autogeneratecolumns="False" Commented Mar 4, 2015 at 11:52
  • If the onrowdatabound is not fired for each row, then probably there is something wrong with the data source that you are supplying. Can you try convert the LINQ query results into a list and use that as a data source. Commented Mar 4, 2015 at 11:56

1 Answer 1

1

In your markup you have this line which is invalid:

<asp:DropDownList ID="Name" runat="server" Text='<%# Bind("Name") %>'></asp:TextBox>

Firstly because you open a DropDownList tag and close a TextBox tag. (I'm assuming this is an error when asking the question and altering your code).

Secondly Text='<%# Bind("Name") %>' is not valid there (looks like this is half of a TextBox delcaration?

I think what you're trying to do is set the SelectedValue of the Dropdown to be the Name of from the Datasource something like this:

<asp:GridView ID="DG_Table" runat="server" style="z-index: 1;autogeneratecolumns="False" 
onrowcommand="DG_Table_RowCommand"  
onrowdatabound="onrowdatabound">  

   <Columns>
     <asp:TemplateField HeaderText="Name" >
      <ItemTemplate>
         <asp:HiddenField id="hdn_Name" runat="server" value='<%# Eval("Name") %>' />
         <asp:DropDownList ID="Name" runat="server" />
      </ItemTemplate>
   <asp:TemplateField HeaderText="field1" >
      <ItemTemplate>
        <asp:TextBox ID="field1" runat="server" Text='<%# Eval("FieldValue") %>'></asp:TextBox>
     </ItemTemplate>
 </Columns>
 </asp:GridView>

CodeBehind:

public void onrowdatabound(object sender, GridViewRowEventArgs e)
{

    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        //check if is in edit mode
        if ((e.Row.RowState & DataControlRowState.Edit) > 0)
        {
               DropDownList dropdownlist = DropDownList)e.Row.FindControl("Name");
               dropdownlist.DataSource = new List<string>() { "Pete", "Jack", "Steve", "Mike", "Rob", "Jim", "Eric" };
               dropdownlist.DataBind();
               var nameField = e.Row.FindControl("hdn_Name") as HiddenField;
               if(nameField != null)
               {
                   dropdownlist.SelectedValue = nameField.Value;
               }
        }
    }
 }
Sign up to request clarification or add additional context in comments.

5 Comments

Thx for correcting. Indeed, I did mismatch DropDownList and TextBox and had to remove the Text field. Your solution nearly works for me. I still have an issue with this line : dropdownlist.SelectedValue = nameField.Value; It always returns the first item of the list (Pete in this case). Could there be something wrong with this line?
Try removing this if statement : if ((e.Row.RowState & DataControlRowState.Edit) > 0). I don't think this belongs here for databining?
Yep I had removed it already and still have the issue mentioned: code dropdownlist.SelectedValue = nameField.Value; always picking up the first item of the datasource list
Found the error :) I copy pasted your code. There was a typo : code value='Eval("Name")' instead of code value='<%# Eval("Name") %>' Once fixed, it works as expected. Thanks a ton for your assistance on this issue.
No problem - I've edited the answer to correct that error. Can you mark this as the answer so it helps others as necessary.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.