Update on GridView combobox not updating - asp.net

I am trying to bind the DropDownList(DDL) with my entity datasource. The GridView(GV) is bound to a different EntityDataSource than the DDL. The GV's EntityDataSource has a navigation property 'Bag' for the relationship. In edit mode I can pick a different item, but it does not update the database for that record. I did use the include for the navigations in the EntityDataSource. I am sure the wiring is not correct. I have tried searching with no luck so far. Thanks for the help.
<asp:TemplateField HeaderText="Bag">
<ItemTemplate >
<asp:Label ID="lbEditBag" Text='<%#Eval("Bag.Item1") %>' runat="server" />
</ItemTemplate>
<EditItemTemplate >
<asp:DropDownList runat="server" ID="ddlBags" DataSourceID="edsBags" DataTextField="Amount" DataValueField="BagId" />
</EditItemTemplate>
</asp:TemplateField>

DonA, if you've not found your answer yet I will explain what I have done to do something similar to what your after I believe.
In a gridview I have various asp:TempleteField's, one which is like this:-
<ItemTemplate>
<asp:Label ID="lblActive" runat="server" Text='<%# Bind("Active") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<%--<asp:TextBox ID="txtboxActive" runat="server" Text='<%# Bind("Active") %>' Width="20px" TextMode="SingleLine" CssClass="textboxEdit"></asp:TextBox>--%>
<asp:DropDownList ID="activeDDL" CausesValidation="False" AutoPostBack="False" runat="server"> <asp:ListItem Text="No" Value="0"></asp:ListItem>
<asp:ListItem Text="Yes" Value="1" Selected="True"></asp:ListItem>
</asp:DropDownList>
</EditItemTemplate>
which as you can see has two dropdownlist items in the EditItemTemplete (I also left in similar code to yours that I used to use to bind to a database for the DDL values but I don't use anymore so is commented out)
then alongside the ID, runat="server", DataKeyNames, etc. in
<asp:Gridview ID=""...
i have
OnRowUpdated="info_GridView_RowUpdated"
This then runs in my C# code behind an SQL function to update the database table with the setting from the DDL, like so (I have also put in a few other Gridview.Databind() to reset my other gridviews)
protected void info_GridView_RowUpdated(object sender, GridViewUpdatedEventArgs e)
{
// The update operation was successful. Retrieve the row being edited.
int index = info_GridView.EditIndex;
GridViewRow row = info_GridView.Rows[index];
int itemID = Convert.ToInt32(row.Cells[4].Text); // Cells[4] is only one available as others are being edited!
// update Active value in the database //
comm = new SqlCommand("UPDATE Products SET Active=#active WHERE ItemID=#itemID", objConn);
comm.Parameters.AddWithValue("#active", ddlValue); // this stores DDL value in database
comm.Parameters.AddWithValue("#itemID", itemID);// Convert.ToInt32(propertyRefTextBox.Text));
objConn.Open();
comm.ExecuteNonQuery();
objConn.Close();
// force update and reset selectedIndex of other gridviews //
Category_GridView.DataBind();
editImages_GridView.DataBind();
Category_GridView.SelectedIndex = -1;
editImages_GridView.SelectedIndex = -1;
}
hope the above helps.
Trev.

Related

How to check for duplicate entries in a gridview and prevent them

I am relatively new to programming and I am having trouble figuring out how to detect and prevent a user from entering in duplicate values into a gridview I have containing multiple controls. Currently I am using a foreach loop to loop through the controls that contain the values that cannot be duplicates and it works for the most part, however when I edit the first record in a table and try to "update" the record, even if I haven't changed any values, I receive a null reference exception and I don't know why. I have attached any pertinent code below and would appreciate any and all help to come to a solution.
Please excuse the long post, I am trying to be as thorough as possible without adding irrelevant information.
To start I have a grid view with a series of controls in it allowing a user to enter information into our database. The gridview and the relevant controls can be seen below.
<asp:GridView ID="GridView2" runat="server"
EmptyDataText="No Miscellaneous" AutoGenerateColumns="False"
ShowHeaderWhenEmpty="True" DataKeyNames="RecID"
ShowFooter="True" DataSourceID="SqlDataSource7" Width="95%"
OnRowDataBound="OnRowDataBound" >
<EmptyDataTemplate>
<asp:DropDownList ID="ddlMiscEquipmentNew" runat="server" DataSourceID="SqlDataSourcePartEquipment" DataValueField="RecID"
DataTextField="EquipmentPart" AppendDataBoundItems="True" AutoPostBack="True" Width="220px" Height="20px" style="margin-left: 70px;" >
<asp:ListItem Value="0">---SELECT---</asp:ListItem>
</asp:DropDownList>
<asp:DropDownList ID="ddlMiscNew" runat="server" DataSourceID="SqlDataSourceMisc" DataValueField="RecID" DataTextField="Description"
AppendDataBoundItems="true" Width="220px" Height="20px" AutoPostBack="True" OnSelectedIndexChanged="ddlMiscNew_SelectedIndexChanged"
OnDataBound="ddlMiscNew_DataBinding">
<asp:ListItem Value="0">---SELECT---</asp:ListItem>
</asp:DropDownList>
<asp:TextBox ID="txtMiscQuantityNew" runat="server" Width="95px" Style="margin-left: 68px;" AutoPostBack="True" OnTextChanged="txtMiscQuantityNew_TextChanged" />
<asp:TextBox ID="txtMiscCostNew" runat="server" Width="95px" Text="0" ReadOnly="True" />
<asp:TextBox ID="txtMiscRequestedNew" runat="server" Width="95px" Text="0" ReadOnly="True" />
<asp:TextBox ID="txtMiscTaxNew" runat="server" Width="95px" Text="0" />
<asp:Button ID="InsertDetail" runat="server" CommandName="InsertDetail" Height="25px" Text="Add Detail" Width="85px" UseSubmitBehavior="True" />
</EmptyDataTemplate>
<AlternatingRowStyle BackColor="#CCCCCC" />
<Columns>
<asp:CommandField ShowEditButton="True" FooterText="Add -->" ShowDeleteButton="true" HeaderStyle-Width="70px" />
<asp:BoundField DataField="RecID" HeaderText="RecID" SortExpression="RecID" ReadOnly="True" Visible="False" />
<asp:TemplateField HeaderText="Miscellaneous" ItemStyle-HorizontalAlign="center">
<ItemTemplate>
<asp:Label ID="lblMiscEquipmentAdd" Text='<%# Bind("EquipmentType") %>' runat="server" Width="220px" />
<asp:Label ID="lblMiscDescriptionAdd" Text='<%# Bind("MiscDescription") %>' runat="server" Width="220px" />
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="ddlMiscEquipmentEdit" runat="server" DataSourceID="SqlDataSourcePartEquipment" DataValueField="RecID" DataTextField="EquipmentPart" SelectedValue='<%# Eval("EquipmentID") %>'
AppendDataBoundItems="True" AutoPostBack="True" Width="220px" Height="20px">
<asp:ListItem Value="0">---SELECT---</asp:ListItem>
</asp:DropDownList>
<asp:DropDownList ID="ddlMiscEdit" runat="server" DataSourceID="SqlDataSourceMisc" DataValueField="RecID" DataTextField="Description" SelectedValue='<%# Eval("MiscType") %>' AppendDataBoundItems="True" Width="220px" Height="20px" AutoPostBack="True" OnSelectedIndexChanged="ddlMiscEdit_SelectedIndexChanged">
<asp:ListItem Value="0">---SELECT---</asp:ListItem>
</asp:DropDownList>
</EditItemTemplate>
<FooterTemplate>
<asp:DropDownList ID="ddlMiscEquipmentInsert" runat="server" DataSourceID="SqlDataSourcePartEquipment" DataValueField="RecID" DataTextField="EquipmentPart"
AppendDataBoundItems="True" Width="220px" Height="20px" style="margin-left: 29px;">
<asp:ListItem Value="0">---SELECT---</asp:ListItem>
</asp:DropDownList>
<asp:DropDownList ID="ddlMiscInsert" runat="server" DataSourceID="SqlDataSourceMisc" DataValueField="RecID" DataTextField="Description" AppendDataBoundItems="True" Width="220px" Height="20px" AutoPostBack="True" OnSelectedIndexChanged="ddlMiscInsert_SelectedIndexChanged">
<asp:ListItem Value="0">---SELECT---</asp:ListItem>
</asp:DropDownList>
</FooterTemplate>
</asp:TemplateField>
There are more controls in the gridview but these are where the problem lies. As you can see there are a number of drop down lists and textboxes, the controls in question are the drop down list "ddlMiscEdit" in the edit item template and the label "lblMiscDescriptionAdd". When the user makes a selection in the aforementioned ddl and proceeds to hit the insert detail button at the end of each row it adds the values to the gridview, and in turn they are added to my database through a row command event. This works as intended, the problem I run into is when a user trys to edit the first row of the gridview and changes the value for ddlMiscEdit, it triggers a null reference exception for the label lblMiscDescriptionAdd.
In order to detect duplicates I have a For Each loop in the selectedIndexChanged event for the ddlMiscEdit drop down as shown below.
For Each row In GridView2.Rows
Dim miscdescription As Label = (CType(row.FindControl("lblMiscDescriptionAdd"), Label))
If miscdescription.Text = ddlMiscEdit.SelectedItem.Text Then
lblErrorMisc.Text = "Miscellaneous items can only be claimed once"
Return
Else
lblErrorMisc.Text = ""
Return
End If
Next
I am thinking this exception has to do with the fact that when the user clicks edit it activates the drop down list and hides the label, thus when it comes to the loop "lblMiscDescriptionAdd" doesn't exist in that specific context.
I have also tried putting the foreach loop in the row command event for the gridview in the "Update" commandName section, which leads to the same issue but in a different place. When this loop is in the Update section mentioned above, instead of receiving this exception on the first record of the gridview I receive it in the second/third/fourth record, basically everything except the first record.
I use that same foreach loop in the InsertDetail command and it works as intended preventing duplicate values from being entered into the gridview, the exception only appears when I am trying to edit a given row depending on where I put the loop.
I apologize for the long post but I don't really know how to simplify my issue beyond what I have done here. I am pretty new to programming so I don't know if I could go about doing this in a better/more efficient manner, but any help/critiques would be greatly appreciated as I am at a loss as to how to fix this problem. Thank you in advance for any effort on your part for helping me solve this.
To make a long story short?
Don't try and process the GV.What happens if other users are adding data. You may well not have re-loaded the grid with updated data.
In your save code for the one record, simple hit/pull/query the main database and check for the record. That way you not messing around all day trying to process and pull values out of the GV.
Always try to think in terms of data management, not trying to use the actual GV as some kind of database - it only for display, and selecting the data to edit, but to check for duplicates, then simple query the database for that information and check if such records already exist.
For example, I have a simple GV with some hotels. (that working example you can try here: http://www.kallal.ca/Website11/WebForm2 ).
So, I have a add button to allow adding of a new reocrd. And I also have a "save" button. It would be in that save button that I simple add code to check say if the hotel name already exists in the database, and not allow that addition.
And what happens with edits? If a user edits existing, and again changes a name to some existing value, then again you have to deal with code to test/check that case.
So, be it adding, or editing, you need to check for that duplicate.
The code thus becomes rather simple. My save button code thus with code to check for the hotel already existing could/would look/work like this:
Protected Sub cmdSave_ServerClick(sender As Object, e As EventArgs)
' check for dupliate hotel name when saving or adding new reocrd.
Dim intPK As Integer = ViewState("PK")
Dim strSQL As String =
"SELECT HotelName FROM tblHotelsA
WHERE HotelName = #HotelName AND ID <> #ID"
Dim cmdSQL As New SqlCommand(strSQL)
cmdSQL.Parameters.Add("#HotelName", SqlDbType.NVarChar).Value = txtHotel.Text
cmdSQL.Parameters.Add("#ID", SqlDbType.NVarChar).Value = intPK
Dim rstDataCheck As DataTable = MyrstP(cmdSQL)
If rstDataCheck.Rows.Count > 0 Then
' we have a duplicate hotel, don't allow adding!
' code here to inform user that this is a duplicate
' hotel and you can't add it.
Me.MyCustomMessage.InnerText = "Can't add this hotel - duplicate"
Exit Sub
End If
' code here to save the edit back to database
strSQL = "SELECT * FROM tblHotelsA WHERE ID = " & intPK
Using conn = New SqlConnection(My.Settings.TEST4)
Using cmdSQL2 = New SqlCommand(strSQL, conn)
conn.Open()
Dim da As New SqlDataAdapter(cmdSQL2)
Dim daU As New SqlCommandBuilder(da)
Dim rstData As New DataTable
rstData.Load(cmdSQL2.ExecuteReader)
With rstData.Rows(0)
.Item("HotelName") = txtHotel.Text
.Item("FirstName") = tFN.Text
.Item("LastName") = tLN.Text
.Item("City") = tCity.Text
.Item("Province") = tProvince.Text
.Item("Description") = txtNotes.Text
.Item("Active") = chkActive.Checked
.Item("Balcony") = chkBalcony.Checked
.Item("Smoking") = chkSmoking.Checked
End With
da.Update(rstData)
End Using
End Using
LoadGrid() ' refrsh grid to show any new edits
ShowGrid(True) ' hide edit area, show grid
End Sub
So, in action, then the above will look like this.
We will edit the record and try to create a duplicate.

Need to set 1st value as select in Drop down list when the data source is table in database

<asp:DropDownList ID="ddl_Role" runat="server" DataSourceID="Sql_role"
DataTextField="Role_Name" DataValueField="Role_ID">
</asp:DropDownList>
<asp:SqlDataSource ID="Sql_role" runat="server"
ConnectionString="<%$ ConnectionStrings:Mytime_role %>"
SelectCommand="SELECT * FROM [Role_Alert]"></asp:SqlDataSource>
<asp:RequiredFieldValidator ID="Rfv_role" runat="server" ControlToValidate="ddl_role"
Display="Dynamic" ErrorMessage="*Role is Required field" Font-Italic="True" ForeColor="Red"
InitialValue="0"></asp:RequiredFieldValidator>
it gives only the starting text in database table as first value in Drop down list .so i need select as default one then the remaining list as usual
You set the selectedItem of the dropdownlist after the DataBind method.
dlTest.DataSource = // some datasource;
dlTest.DataBind();
dlTest.Items.FindByValue(search_value).Selected = true;
You can search for the item, either using FindByText or FindByValue. Alternatively, if you could store the selected item text/value, then you can set the dropdownlist selected item in the DataBound event. This will be fired after the data has been binded to dropdownlist.
protected void dlTest_DataBound(object sender, EventArgs e) {
dlTest.Items.FindByValue(search_value).Selected = true;
}
<asp:DropDownList ID="DropDownListID" AppendDataBoundItems="true" runat="server">
<asp:ListItem Text="Default text" Value="Default value" />
</asp:DropDownList>
Add a default item and also attribute AppendDataBoundItems="true"

PostBack DataBind error: "Ensure that the control is added to the page before calling DataBind."

I have a program that allows the user to use a few dropdowns to pick a topic and attribute, then the data are pulled that match on both of those conditions. In the gridview are a lot of templatefields use textboxes for instant editing (a submit button saves all changes) as well as a template with a dropdown bound to a parameter. This was all working hunky-dory for quite a while.
Then, we changed some of the data in the tables (keeping all the same field names) and now the page loads perfectly fine on launch but then as soon as you select something different in any of the drilldown dropdowns the page fails. I get an error saying
"The DropDownList control 'TagDDL' does not have a naming container.
Ensure that the control is added to the page before calling DataBind."
(TagDDL is the dropdown in the templatefield in gridview). If I simply remove this templatefield, I get a similar (though different) error on a hyperlinkfield, removing this gives me an error in a boundfield, so obviously it's not tied to any one thing.
My idea is that it has something to do with how databinding works on post-back, since the page loads perfectly initially, the dropdowns have 'Enable PostBack' and the error messages refer to DataBind. Any ideas?
The SqlDataSource that builds Gridview (leaving out the drilldown dropdowns for now)
<asp:SqlDataSource ID="MasterTable" runat="server"
ConnectionString="<%$ ConnectionStrings:spvConnectionString %>"
SelectCommand="exec pmtv2.maintable_display 1, #IPG_Assigned, #CompetitorName, #enterprise_zone, #Banner, #BrandName"
<SelectParameters>
<asp:ControlParameter ControlID="ChooseBanner" Name="Banner" PropertyName="SelectedValue" Type="String" />
<asp:ControlParameter ControlID="ChooseIPGs" Name="IPG_Assigned" PropertyName="SelectedValue" Type="Int32" />
<asp:ControlParameter ControlID="ChooseBrands" Name="BrandName" PropertyName="SelectedValue" Type="String" />
<asp:ControlParameter ControlID="ChooseComps" Name="CompetitorName" PropertyName="SelectedValue" Type="String" />
<asp:ControlParameter ControlID="ChooseZone" Name="enterprise_zone" PropertyName="SelectedValue" Type="Int32" />
</SelectParameters>
<div id="MasterDiv" style="width:90%">
<asp:GridView ID="MasterDisplay" runat="server"
AllowSorting="True" AutoGenerateColumns="False"
DataKeyNames="productKey,banner,enterprise_zone,userID" DataSourceID="MasterTable"
OnRowDataBound="MasterDisplay_RowDataBound"
OnSorting="MasterDisplay_Sorting"
class="mGrid" AlternatingRowStyle-CssClass="mGridAlt">
</AlternatingRowStyle>
<Columns>
<asp:TemplateField HeaderText="Description" SortExpression="productdescriptionlong">
<ItemTemplate>
<a href="javascript:openPopup('JustinPractice4.aspx?UPC=<%# Eval("UPC") %>
&banner=<%# Eval("banner") %>&enterprise_zone=<%# Eval("enterprise_zone") %>')"><%# Eval("productdescriptionlong")%></a>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="BrandName" HeaderText="Brand"
SortExpression="BrandName" />
<asp:TemplateField HeaderText="New Price" SortExpression="new_base_retail">
<ItemTemplate>
<asp:TextBox ID="RWNextPrice" runat="server"
Text='<%# Bind("new_base_retail", "{0:N2}") %>' Width="60px"
class="calculate" onchange="lineItemRipple(this)"
Visible='<%# ShowBox %>'></asp:TextBox>
<asp:Label ID="RNextPrice" runat="server" Text='<%# Eval("new_base_retail", "{0:c}") %>'
Visible='<%# ShowLabel %>'></asp:Label>
<asp:HiddenField ID="lineCode" runat="server" Value='<%# Eval("line_code") %>'/>
</ItemTemplate>
</asp:TemplateField>
<asp:ImageField DataImageURLField="unique_flags" HeaderText="Flags"
DataImageURLFormatString="Media/Images/{0}.png" SortExpression="unique_flags"/>
<asp:TemplateField HeaderText="Tag Type" SortExpression="tag_type">
<ItemTemplate>
<asp:DropDownList ID="TagDDL" runat="server"
DataSourceID="dimTags"
DataTextField="Tag_type_name"
DataValueField="Tag_type_name"
SelectedValue='<%#Bind("tag_type") %>'
visible='<%#ShowBox %>'>
</asp:DropDownList>
<asp:Label ID="TagR" runat="server"
Text='<%# Eval("tag_type") %>'
Visible='<%# ShowLabel %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button ID="Commit" runat="server" Text="Commit Changes" OnClick="Commit_Click"
class="button"/>
and the relevant code behind:
protected void Page_Load(object sender, EventArgs e) {
ErrorMsg.Text = "test45";
}
protected void MasterDisplay_RowDataBound(object sender, GridViewRowEventArgs e) {
DataSourceSelectArguments sr = new DataSourceSelectArguments();
DataView dv = (DataView)CheckForCommit.Select(sr);
if (dv.Count != 0) {
CommittedOrNot.Text = dv[0][0].ToString();
}
//pulling results from a SqlDataSource confirming presence of data
//calculations to maintain a running tally of certain fields for later use
}
protected void Commit_Click(Object sender, EventArgs e) {
string tagValue = "FLAG";
foreach (GridViewRow gvr in MasterDisplay.Rows) {
tagValue = ((DropDownList)gvr.FindControl("TagDDL")).SelectedValue;
MasterDisplay.UpdateRow(gvr.RowIndex, false);
} //for every row, update it
MasterDisplay.DataBind();
}
It was a simple error of trying to add to a DDL before I had actually pulled the data needed to bind it. Changing the order of things slightly did the trick
I am glad you found your answer. I had a similar issue on a UserControl (ascx) that was being loaded a run-time. I, too, had made a change to my data source and the corresponding sql data sources. (In my case, I was replacing the sql data sources with an entity model.)
What I found was that one of my controls would bind to the new data source (via the code behind) with no problems. The code looked as follows:
gridSomeData.DataSource = controller.GetListOfAssociatedParts();
gridSomeData.DataBind();
However, in the same method, the next section of code would fail when the DataBind() method was called. The code looked as follows:
drpDataList.DataSource = controller.GetListOfParts();
drpDataList.DataTextField = "PartID"
drpDataList.DataValueField = "PartKey"
drpDataList.DataBind();
It turned out, that when I removed the prior ASCX markup for the SqlDataSource objects, I failed to remove the reference in the DataSourceID attribute of the drop down control. So when I called the DataBind() method, the binding engine checked the attributes of the control, found a name DataSourceID, and immediately went looking for it in the control hierarchy of the UserControl. When the binding engine failed to find the object, it threw the exception "The DropDownList control [...] does not have a naming container..."
I will admit that this particular exception is somewhat misleading, as it is really the binder being confused over which instructions to follow for the data source (the code behind, or the markup in the ascx file).
I hope this helps with some perspective. :)

ASP .Net Gridview bind to data only when clicking update

Here's how I want the control to work. Click edit on a row in gridview. There's a textbox in one of the columns, I would like it to be blank even though there's data in the database for that column, but when I click update I would like whatever new text the user entered to update the database for that column. It would be one-way databinding, but the other way?
Here's how I did it using an sql datasource with the select,update and delete methods generated.
First, you'll need to make any column that you want to edit like this a template field with an item template and and edit item template:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" DataSourceID="SqlDataSource1"
onrowupdating="GridView1_RowUpdating">
<Columns>
<asp:TemplateField HeaderText="City" SortExpression="City">
<ItemTemplate>
<asp:Label runat="server" Text='<%# Eval("City") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox runat="server" ID="txtCityEdit" Text=""></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Next handle the gridview's on update event:
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
//find the value control who's value you want
TextBox tb = (TextBox)GridView1.Rows[e.RowIndex].FindControl("txtCityEdit");
//since we are not using a bound column for city we need to explicitly insert the value
//into the update parameter.
SqlDataSource1.UpdateParameters["City"].DefaultValue = tb.Text;
}
Even if you are using something other than an SQL Datasource this should be the basic solution.
// Find notes textbox
TextBox tb = (TextBox)MyActiveReferrals.Rows[e.RowIndex].FindControl("NotesTextBox");
e.NewValues.Add("Notes", tb.Text);
I used a linq data source.

How do I data bind a drop down list in a gridview from a database table using VB?

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
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.
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
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.
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!

Resources