QUESTION: I'm working with a DataGrid. When editing a row, I would like to have one of my fields be a DropDownList. I would much rather be able to bind that DropDownList to a table in a DataSet so when new key/values are setup in the database they flow through to my aspx page without having to fuss with it. Please, example in VB.
David Vias
|
ANWSER:
It has come to our attention that this article didn't completly anwser the proposed question. Because of this fact
we are adding yet another one. In this code example we will be demonstrating how not only show a
DropDownList control populated from a database in an EditItemColumn, but how additionally show a TextBox to edit
the value of the DropDownlist. Because we are all intelligent programmers I am not going to give a huge
background on how editing works and how to use the DataGrid, instead I am going to jump right into a code example. Listing 1.1
contains the code we will be working with today:
|
|
Listing 1.1 - Code Example
|
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<script language="c#" runat="server">
SqlConnection SqlCon = new SqlConnection(ConfigurationSettings.AppSettings["constringNorthwind);
protected void Page_Load(Object sender, EventArgs e){
if (! IsPostBack){
BindGrid();
}
}
protected void BindGrid(){
SqlDataAdapter SqlDa = new SqlDataAdapter("SELECT S.*, (SELECT COUNT(*) FROM Products P WHERE P.SupplierID = S.SupplierID) [ProductCount] FROM Suppliers S", SqlCon);
DataSet ds = new DataSet();
SqlDa.Fill(ds, "Suppliers");
MyDataGrid.DataSource = ds.Tables["Suppliers"];
MyDataGrid.DataBind();
}
protected DataTable GetProducts(int SupplierID){
SqlDataAdapter SqlDa = new SqlDataAdapter("SELECT ProductName, ProductID FROM Products WHERE SupplierID = @SupplierID", SqlCon);
SqlDa.SelectCommand.Parameters.Add(new SqlParameter("@SupplierID", SqlDbType.VarChar, 100));
SqlDa.SelectCommand.Parameters["@SupplierID"].Value = SupplierID;
DataSet ds = new DataSet();
SqlDa.Fill(ds, "ProductList");
return ds.Tables["ProductList"];
}
protected void MyDataGrid_Edit(Object sender, DataGridCommandEventArgs e) {
MyDataGrid.EditItemIndex = e.Item.ItemIndex;
BindGrid();
}
protected void MyDataGrid_Cancel(Object sender, DataGridCommandEventArgs e) {
MyDataGrid.EditItemIndex = -1;
BindGrid();
}
protected void MyDataGrid_Update(Object sender, DataGridCommandEventArgs e) {
string ChangeProductNameFrom = (string)((DropDownList)(e.Item.FindControl("edit_Product"))).SelectedItem.Text;
string ChangeProductNameTo = (string)((TextBox)(e.Item.FindControl("NewProductName"))).Text;
Message.Text = ChangeProductNameFrom + " <B>HAS BEEN CHANGED TO</B> " + ChangeProductNameTo;
MyDataGrid.EditItemIndex = -1;
BindGrid();
}
</script>
<html>
<body>
<form runat="server">
<center>
<asp:Label id="Message" MaintainState="false" ForeColor="#CC3300" Font-Size="11pt" runat="server"/><p>
<ASP:DataGrid
id="MyDataGrid"
runat="server"
Width="800"
CellPadding=3
CellSpacing="0"
OnEditCommand="MyDataGrid_Edit"
OnCancelCommand="MyDataGrid_Cancel"
OnUpdateCommand="MyDataGrid_Update"
DataKeyField="SupplierID"
BorderColor="Tan"
ShowFooter="false"
Font-Name="Verdana"
Font-Size="8pt"
HeaderStyle-Font-Bold="True"
HeaderStyle-BackColor="Maroon"
AutoGenerateColumns="False"
HeaderStyle-ForeColor="Tan" >
<columns>
<asp:EditCommandColumn
EditText="Edit"
CancelText="Cancel"
UpdateText="Update"
ItemStyle-VerticalAlign="top" />
<asp:BoundColumn
HeaderText="ID"
ReadOnly="True"
DataField="SupplierID"
ItemStyle-Wrap="false"
ItemStyle-VerticalAlign="top" />
<asp:BoundColumn
HeaderText="ID"
ReadOnly="True"
DataField="CompanyName"
ItemStyle-Wrap="false"
ItemStyle-VerticalAlign="top" />
<asp:TemplateColumn HeaderText="Products" >
<ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "ProductCount") %> Products
</ItemTemplate>
<EditItemTemplate>
<TABLE Width="100%" CellPadding="0" CellSpacing="0" Border="0">
<TR>
<TD Style="font-size:8" Width="20%">
<b>CHANGE -</b>
</TD>
<TD>
<asp:DropDownList
Runat="server"
Id="edit_Product"
DataSource='<%# GetProducts((int)DataBinder.Eval(Container.DataItem, "SupplierID")) %>'
DataTextField="ProductName"
DataValueField="ProductID"
Width="200" />
</TD>
</TR>
<TR>
<TD Style="font-size:8" Width="20%">
<b>TO - </b>
</TD>
<TD>
<asp:TextBox
id="NewProductName"
runat="Server"
Width="200" />
</TD>
</TR>
</TABLE>
</EditItemTemplate>
</asp:TemplateColumn>
</columns>
</asp:DataGrid>
</center>
</form>
</body>
</html>
|
|
Most likely the only new thing in this code example is found in the EditItemColumn of the TemplateColumn.
You will find two objects here, first a DropDownList control and second is a TextBox. You'll notice that
the DropDownList.DataSource is set to the GetProducts method which returns a DataTable. The GetProducts
method expects one parameter, the SupplierID and uses this value to retrieve all the products that the particular supplier has.
When this page first loads it will look like the following:
Figure 1.1
In the products column there is just the total number of product each supplier has. Once a row is
put into edit mode you'll have a page like the following:
Figure 1.2
Now in the products column there is a DropDownList with a list of all the suppliers products and a TextBox you can use to change a product name. (sorry thats the best I could come up with).
If you want to go ahead and put the DataGrid into edit mode, select a product, change its name, and hit update you will see a page like the following:
Figure 1.3
Within the DataGrid_Update method I retrieve the selected item from the DropDownList and the value of the TextBox and write out to the page as seen above.
|
|
Conclusion
|
|
Hopefully, this code example will anwser a few questions for you regarding binding other list controls within a container control! Obviously, this
example is not optimized for speed, but it should give you the general idea.
|
|
Run Example
|
|
[ run ]
|
|