views:

772

answers:

4

So in this gridview, there is a column for status and I want to have a drop down list with Pass, Pending, Fail appear when the edit button is clicked. These values are already in a table, so I need to somehow bind from this table to each ddl for every row.

Here is the column from the gridview. As you can see, I would like to just have a label showing when not in edit mode, and a ddl when the edit button is pressed

    <asp:TemplateField HeaderText="During Production Status" SortExpression="DuringProductionStatus">
        <EditItemTemplate>
             <asp:DropDownList ID="ddlStatus" runat="server" datavaluefield="Name" 
                 datatextfield="Name" DataSource="*What goes here?*"> />
        </EditItemTemplate>
        <ItemTemplate>
            <asp:Label ID="lblStatus" runat="server"
                Text='I don't understand how to get this from the ddl' />
        </ItemTemplate>
    </asp:TemplateField>

For clarity's sake, my table is named Status, and the database is named DirectImport

A: 

In the winforms world I pull my objects from the DB into a List(Of Whatever) and use the list as the datasource.

This also lets me add extra "convenience" fields in the object so that I can populate it with stuff from other tables.

I don't know asp.net at all so if you can do something similar, it might help.

John at CashCommons
A: 

A really quick solution is to create a custom web control for the status dropdown. The control will always contain the same data. When it renders you populate the datasource. When it gets added to the gridview, the data will be in the drop down. Hope that helps!

DrPennybags
+1  A: 

There's a few steps to go through here - none of them are particularly difficult, but they can be a bit fiddly (IMHO). The good news is once you've got this working once, it gets easier to do it again!

I'm assuming you've got a <asp:*DataSource> control on your page - my preference is for an ObjectDataSource but I don't think it matters, I think a SqlDataSource works equally well. I've never tried doing this with GridView.DataSource = MyDataSet in code-behind, so I don't know whether that would work or not, but my assumption is that it wouldn't as you wouldn't get the proper two-way binding that you want. This data source feeds your grid with your main data. The key point here is that your database query must return both the Status text field and the Status id.

So your gridview will now look something like:

<asp:objectdatasource runat="server" id="MainDataSource" ... />  
<asp:gridview runat="server" id="MyGridView" DataSourceID="MainDataSource">  
    <Columns>  
        <asp:TemplateField HeaderText="During Production Status" SortExpression="DuringProductionStatus">  
            <ItemTemplate>  
                <asp:Label ID="lblStatus" runat="server"  
                   Text="<%# Bind('Status') %>" />  
           </ItemTemplate>  
        </asp:TemplateField>  
     </Columns>  
</asp:gridview>

The Text="<%# Bind('Status') %>" is the bit you're missing to get the status text into the grid.

Now add a second data source into your markup that reads in the set of values from the Status table.

<asp:objectdatasource runat="server" id="StatusObjectDataSource" ... />

And add the EditItemTemplate into the GridView, which is bound to the Status DataSource.

<EditItemTemplate>
    <asp:DropDownList ID="ddlStatus" runat="server" datavaluefield="StatusID" 
        datatextfield="Status" DataSourceID="StatusObjectDataSource"  
        SelectedValue="<%# Bind('StatusId') %>" />
</EditItemTemplate>

The SelectedValue="<%# Bind('StatusId') %>" is what connects up the two datasets so that when you flip a row into Edit mode, the dropdownlist has the correct item already selected, and when you then save it you've got the Status ID to put into your database.
And you're done.

PhilPursglove
Thanks for the great answer. I've never used that kind of datasource yet, so I'm a little confused on what actually goes in that ellipses part.
Justen
PhilPursglove
+1  A: 

I have used the RowDataBound event. Here is a small code snippet. HTH

you would have an ItemTemplate in your aspx/ascx

<asp:TemplateField HeaderText="Column Headings">
                <ItemTemplate>
                  <asp:DropDownList ID="ddlName" runat="server" Width="150"></asp:DropDownList>
                </ItemTemplate>
              </asp:TemplateField>

and in your code behind, you will have

protected void grdDataMap_RowDataBound(object sender, GridViewRowEventArgs e) 
{

    if (e.Row.RowType == DataControlRowType.DataRow)
    {
       DropDownList ddl = (DropDownList)e.Row.FindControl("ddlName");
       ddl.DataSource = someList;//the source of your dropdown
      ddl.DataBind();

    }

}

so when you bind your grid with grdDataMap.Databind (assuming your grid id is grdDataMap), row databound event will be called for each row (including header/footer, and thats the reason you check RowType)

so you can probably decide what controls/columns to hide/show/bind inside this row databound event

ram