Image showing when a control is added to EditItemTemplate
.
Introduction
Based on my previous control "Multiple Column DropDownList for ASP.NET", I received many emails asking for the same control to be used in the DataGrid
for web applications. Here we go.. This control can be used as the regular MS DropDownList
in the DataGrid
and also as a regular dropdownlist. It has all the properties, like DataTextField
, DataValueField
, DataSource
, SelectedIndex
etc. The download file contains the samples both in VB.NET and C#. In this sample, I have used the Northwind database of SQL Server.
Building the Control
The following web server controls were used to build this control:
TextBox
Label
Panel
Adding the Control to DataGrid
This control can be added either to the ItemTemplate
or EditItemTemplate
of the DataGrid
through Property Builder.
- Drop a
DataGrid
onto your webform.
- Right click the
DataGrid
and select Property Builder and select Columns.
- A bound column may or may not be required, I have shown samples of both.
- Add two bound columns, set the header and the text field: SupplierID and CompanyName.
- Add one Template Column and set the header text to Products.
- Uncheck the checkbox "Create columns automatically at run time".
- Click OK.
- Now right click the
DataGrid
and select Edit Template, now either you could add this in ItemTemplate
or EditItemTemplate
.
- Set the properties of the control, like
CssClass
, GridRowcolor
, DataTextfield
etc.
- Close the template box.
Points to Note:
The DataValueField
property is readonly
, which means you cannot set the value, so make sure that in your query, the row value field is always the first column, which will not be displayed in the dropdown. The DataTextField
returns an integer value, so while setting this property, type the column position from your "SELECT
" statement, which needs to get displayed in the textbox. (For e.g., to display the second column "LastName" in the textbox, set DataValueField
=2.) If your DataGrid
is inside the "Table
/Div
/Span
", then make sure the "Position
" attribute in the "Style
" property is set to absolute
, and if not used in any of these tags, then set the DataGrid
's Style
property.
Make sure that the HorizontalAlign
and VerticalAlign
properties of the ItemStyle
of your DataGrid
is set as shown, else the control may not be positioned properly inside the DataGrid
. E.g.:
<ItemStyle HorizontalAlign="Left" VerticalAlign="Top"></ItemStyle>
See the code below. E.g., to populate the dropdown with FirstName
and LastName
:
SELECT Employeeid,Firstname,LastName
From Employees
Now if added in the EditItemTemplate
(based on your requirement, bounded column may or may not be required), in my sample I used two <BoundColumn>
s:
<ASP:DATAGRID id="jskDataGrid" runat="server"
Font-Size="8pt" HeaderStyle-ForeColor="Tan"
AutoGenerateColumns="False" HeaderStyle-BackColor="Maroon"
HeaderStyle-Font-Bold="True" Font-Name="Verdana" ShowFooter="false"
BorderColor="Tan" DataKeyField="SupplierID"
OnUpdateCommand="MyDataGrid_Update" OnCancelCommand="MyDataGrid_Cancel"
OnEditCommand="MyDataGrid_Edit" CellSpacing="0" CellPadding="3"
Width="800" Style="Position:absolute;Top:0px;Left:0px">
<HeaderStyle Font-Bold="True" ForeColor="Tan" BackColor="Maroon"></HeaderStyle>
<Columns>
<asp:EditCommandColumn ButtonType="LinkButton"
UpdateText="Update" CancelText="Cancel" EditText="Edit">
<ItemStyle VerticalAlign="Top"></ItemStyle>
</asp:EditCommandColumn>
<asp:BoundColumn DataField="SupplierID"
ReadOnly="True" HeaderText="Supplier ID">
<ItemStyle Wrap="False" VerticalAlign="Top"></ItemStyle>
</asp:BoundColumn>
<asp:BoundColumn DataField="CompanyName"
ReadOnly="True" HeaderText="Company Name">
<ItemStyle Wrap="False" VerticalAlign="Top"></ItemStyle>
</asp:BoundColumn>
<asp:TemplateColumn HeaderText="Products">
<ItemStyle HorizontalAlign="Left" VerticalAlign="Top"></ItemStyle>
-->
<%# DataBinder.Eval(Container.DataItem, "ProductName") %>
</ItemTemplate>
<EditItemTemplate>
<TABLE cellSpacing="0" cellPadding="0" width="100%" border="0">
<TR>
<TD>
<jsk:mcDDList id="McDDList1"
Width="200"
SelectedIndex='<%# DataBinder.Eval(Container.DataItem,
"ProductID") %>'
cssClass="cStyle" Runat="server"
DataSource="<%# PopulateDDList()%>"
DataTextField="2">
</jsk:mcDDList>
</TD>
</TR>
</TABLE>
</EditItemTemplate>
</asp:TemplateColumn>
</Columns>
</ASP:DATAGRID>
If you want to show the existing values then add the "SelectedIndex
" property.
Properties
DataTextField
- The field to be shown in the Ccontrol.
DataValueField
- Read only property (value field to identify the row - default is first column {0}).
DataSource
- DataSet
to populate the dropdown.
DDTextboxReadonly
- If false
, can type your own text.
GridRowColor
- OnMouseMove
changes the row color.
GridTextColor
- OnMouseMove
changes the text color.
ListBoxHeight
- Sets the height of the dropdown.
ReturnsValue
- To get the text, set it to false
. To get the value, set it to true
, while updating.
SelectedIndex
- If set, shows the existing value in the dropdown.
Populating the DataGrid
private void Page_Load(object sender, System.EventArgs e)
{
if (! IsPostBack)
{
BindDataGrid();
}
}
protected void BindDataGrid()
{
string sqlStr = "SELECT S.CompanyName, S.SupplierID," +
" P.ProductName, P.ProductID " +
"from Suppliers S inner join Products P " +
"on S.SupplierID = P.SupplierID ";
sqlDa = new SqlDataAdapter(sqlStr, SqlCon);
ds = new DataSet();
sqlDa.Fill(ds, "Prod");
jskDataGrid.DataSource = ds.Tables["Prod"];
jskDataGrid.DataBind();
}
Populating the DropDownList
public DataSet PopulateDDList()
{
string sqlString = " select ProductID, ProductName, " +
"CategoryName as Name,UnitPrice as Price " +
"from Products p inner join Categories c " +
"on p.categoryid = c.categoryid ";
SqlDataAdapter ad = new SqlDataAdapter(sqlString,SqlCon);
DataSet ds = new DataSet();
ad.Fill(ds,"Categories");
return ds;
}
Codes to Edit/Update/Cancel
protected void jskDataGrid_Edit(object sender, DataGridCommandEventArgs e)
{
jskDataGrid.EditItemIndex = e.Item.ItemIndex;
BindDataGrid();
}
protected void jskDataGrid_Cancel(object sender, DataGridCommandEventArgs e)
{
jskDataGrid.EditItemIndex = -1;
BindDataGrid();
}
protected void jskDataGrid_Update(object sender, DataGridCommandEventArgs e)
{
try
{
string itemValue;
string itemText;
((ddList.mcDDList)e.Item.FindControl("McDDList1")).ReturnsValue = true;
itemValue =
((ddList.mcDDList)e.Item.FindControl("McDDList1")).Text.ToString();
((ddList.mcDDList)e.Item.FindControl("McDDList1")).ReturnsValue = false;
itemText =
((ddList.mcDDList)e.Item.FindControl("McDDList1")).Text.ToString();
jskDataGrid.EditItemIndex = -1;
BindDataGrid();
}
catch(Exception ex)
{
Response.Write(ex.Message);
}
finally
{
}
}
Points of Interest
The control is built mostly using JavaScript. There is a property "DDTextboxReadonly
", this property is used to enable/disable the textbox, means either you could select the text from the list or you could type.
Using the Intellisense
As in my previous article, I showed how to use the Intellisense. The zip file contains the .xsd, copy it to the following location:
- C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Packages\schemas\xml
and in the <body>
tag of your aspx page, add the following code:
<body MS_POSITIONING="GridLayout"
xmlns:jsk="urn:http://schemas.ksjControls.com/DGDD/ASPNET">
History
- ver. (1.0) - Initial version (posted 12th May 2005)
- ver. (1.1) - New property has been added,
ListBoxHeight
to adjust the height of the dropdown.
- ver. (1.2) - Control does not expand the
DataGrid
rows.