Hi Jim,
There's an article that addresses this subject.
Top Questions about the DataGrid Web Server Control
http://msdn.microsoft.com/library/en...hTopQuestionsA
boutASPNETDataG ridServerContro l.asp
Here is the relevant section.
Adding Columns Dynamically
You can hide and show columns if you know in advance what columns you need.
Sometimes, however, you do not know that until run time. In that case, you
can create columns dynamically and add them to the grid.
To do so, you create an instance of one of the column classes supported by
the grid — BoundColumn, EditCommandColu mn, ButtonColumn, or
HyperlinkColumn . (You can add template columns to the grid, but it is
slightly more complex. For details, see Creating Web Server Control
Templates Programmaticall y.) Set the column's properties, and then add it
to the grid's Columns collection.
The following example shows how to add two bound columns to a grid.
' Visual Basic
Private Sub Button1_Click(B yVal sender As System.Object, _
ByVal e As System.EventArg s) Handles Button1.Click
'Set data-binding properties of the grid
DataGrid1.AutoG enerateColumns = False
DataGrid1.DataS ource = Me.dsBooks1
DataGrid1.DataM ember = "Books"
DataGrid1.DataK eyField = "bookid"
' Add two columns
Dim dgc_id As New BoundColumn()
dgc_id.DataFiel d = "bookid"
dgc_id.HeaderTe xt = "ID"
dgc_id.ItemStyl e.Width = New Unit(80)
DataGrid1.Colum ns.Add(dgc_id)
Dim dgc_title As New BoundColumn()
dgc_title.DataF ield = "title"
dgc_title.Heade rText = "Title"
DataGrid1.Colum ns.Add(dgc_titl e)
Me.SqlDataAdapt er1.Fill(Me.dsB ooks1)
DataGrid1.DataB ind()
End Sub
// C#
private void Button1_Click(o bject sender, System.EventArg s e)
{
DataGrid1.AutoG enerateColumns = false;
DataGrid1.DataS ource = this.dsBooks1;
DataGrid1.DataM ember = "Books";
DataGrid1.DataK eyField = "bookid";
// Add two columns
BoundColumn dgc_id = new BoundColumn();
dgc_id.DataFiel d = "bookid";
dgc_id.HeaderTe xt = "ID";
dgc_id.ItemStyl e.Width = new Unit(80);
DataGrid1.Colum ns.Add(dgc_id);
BoundColumn dgc_title= new BoundColumn();
dgc_title.DataF ield = "title";
dgc_title.Heade rText = "Title";
DataGrid1.Colum ns.Add(dgc_titl e);
this.sqlDataAda pter1.Fill(this .dsBooks1);
DataGrid1.DataB ind();
}
Any time that you add controls to a page dynamically, you have the problem
of persistence. Dynamically-added controls (or in this case, columns) are
not automatically added to the page's view state, so you are obliged to add
logic to the page to make sure the columns are available with each round
trip.
An excellent way to do this is to override the page's LoadViewState method,
which gives you an early opportunity to reestablish columns in the DataGrid
control. Because the LoadViewState method is called before the Page_Load
event is raised, re-adding columns in the LoadViewState method assures that
they are available for normal manipulation by the time any event code runs.
The following example shows how you would expand the previous example to
restore the columns each time the page runs again. As before, the
Button1_Click handler adds two columns to the grid. (In this example, the
event handler calls a separate routine called AddColumns to do so.) In
addition, the page contains a simple Boolean property called
DynamicColumnsA dded indicating whether the grid has had columns added; the
property persists its value in view state. The LoadViewState method first
calls the base class's LoadViewState method, which extracts view state
information and configures controls with it. If columns were previously
added to the grid (as per the DynamicColumnsA dded property), the method
then re-adds them.
' Visual Basic
Private Property DynamicColumnAd ded() As Boolean
Get
If ViewState("Colu mnAdded") Is Nothing Then
Return False
Else
Return True
End If
End Get
Set(ByVal Value As Boolean)
ViewState("Colu mnAdded") = Value
End Set
End Property
Protected Overrides Sub LoadViewState(B yVal savedState As Object)
MyBase.LoadView State(savedStat e)
If Me.DynamicColum nAdded Then
Me.AddColums()
End If
End Sub
Private Sub Button1_Click(B yVal sender As System.Object, _
ByVal e As System.EventArg s) Handles Button1.Click
' Check property to be sure columns are not added more than once
If Me.DynamicColum nAdded Then
Return
Else
Me.AddColums()
End If
End Sub
Protected Sub AddColums()
' Add two columns
Dim dgc_id As New BoundColumn()
dgc_id.DataFiel d = "instock"
dgc_id.HeaderTe xt = "In Stock?"
dgc_id.ItemStyl e.Width = New Unit(80)
DataGrid1.Colum ns.Add(dgc_id)
Dim dgc_title As New BoundColumn()
dgc_title.DataF ield = "title"
dgc_title.Heade rText = "Title"
DataGrid1.Colum ns.Add(dgc_titl e)
Me.DataGrid1.Da taBind()
Me.DynamicColum nAdded = True
End Sub
// C#
private bool DynamicColumnAd ded{
get
{
object b = ViewState["DynamicColumnA dded"];
return (b == null) ? false : true;
}
set
{
ViewState["DynamicColumnA dded"] = value;
}
}
protected override void LoadViewState(o bject savedState)
{
base.LoadViewSt ate(savedState) ;
if (DynamicColumnA dded)
{
this.AddColumns ();
}
}
private void Button1_Click(o bject sender, System.EventArg s e)
{
if(this.Dynamic ColumnAdded != true)
{
this.AddColumns ();
}
}
private void AddColumns()
{
BoundColumn dgc_id = new BoundColumn();
dgc_id.DataFiel d = "bookid";
dgc_id.HeaderTe xt = "ID";
dgc_id.ItemStyl e.Width = new Unit(80);
DataGrid1.Colum ns.Add(dgc_id);
BoundColumn dgc_title= new BoundColumn();
dgc_title.DataF ield = "title";
dgc_title.Heade rText = "Title";
DataGrid1.Colum ns.Add(dgc_titl e);
this.sqlDataAda pter1.Fill(this .dsBooks1);
DataGrid1.DataB ind();
this.DynamicCol umnAdded = true;
}
Adding New Records to a Data Source Using the DataGrid Control
The DataGrid control allows users to view and edit records, but does not
inherently include the facility to add new ones. However, you can add this
functionality in various ways, all of which involve the following:
Adding a new, blank record to the data source of the grid (in the dataset
or database). If necessary, you will need to assign an ID for the record
and put placeholder values into it for any columns that cannot be null.
Rebinding the DataGrid control to the source.
Putting the grid into edit mode for the new record. You need to be able to
determine where in the grid the new record appears.
Updating the record normally when the user clicks Update, thereby writing
the new record to the source with user-provided values.
The following example shows the process for adding the new record, binding
the grid, and putting it into edit mode. In this example, the data source
is a dataset (DsBooks1 or dsBooks1) containing a table called "Books."
' Visual Basic
Private Sub btnAddRow_Click (ByVal sender As System.Object, _
ByVal e As System.EventArg s) Handles btnAddRow.Click
Dim dr As DataRow = Me.DsBooks1.Boo ks.NewRow
dr("title") = "(New)"
dr("instock") = True
Me.DsBooks1.Boo ks.Rows.InsertA t(dr, 0)
Session("DsBook s") = DsBooks1
DataGrid1.EditI temIndex = 0
DataGrid1.DataB ind()
End Sub
// C#
private void btnAddRow_Click (object sender, System.EventArg s e)
{
DataRow dr = this.dsBooks1.B ooks.NewRow();
dr["title"] = "(New)";
dr["instock"] = true;
this.dsBooks1.B ooks.Rows.Inser tAt(dr, 0);
Session["DsBooks"] = dsBooks1;
DataGrid1.EditI temIndex = 0;
DataGrid1.DataB ind();
}
Some things to notice:
This code runs when a user clicks an Add button somewhere in the page.
The new row is created using the NewRow method. It is then inserted into
the dataset table using the InsertAt method, which allows you to place it
at a specific, predefined location — in this case, as the first record in
the table (that is, the first record in the Rows collection).
Alternatively, you could add it to the end of the table, using the row
count as the value. The important thing is that you know exactly where the
row is in the table.
Because you know that the record is in the first position of the table, you
can set the grid's EditItemIndex value to zero to put the new row into edit
mode. (If you created the row elsewhere in the table, you would set
EditItemIndex to that location instead.)
Because you have a new record in the dataset (but not yet in the database),
you have to keep a copy of the dataset between round trips — you do not
want to refill it from the database and lose the new record. Here, the code
stores it in Session state. You need to reload the dataset from Session
state when the page loads. The following example shows what your Page_Load
handler might look like:
' Visual Basic
Private Sub Page_Load(ByVal sender As System.Object, _
ByVal e As System.EventArg s) Handles MyBase.Load
If Me.IsPostBack Then
DsBooks1 = CType(Session(" DsBooks"), dsBooks)
Else
Me.SqlDataAdapt er1.Fill(Me.DsB ooks1)
Session("DsBook s") = DsBooks1
DataGrid1.DataB ind()
End If
End Sub
// C#
private void Page_Load(objec t sender, System.EventArg s e)
{
if(this.IsPostB ack)
{
dsBooks1 = (dsBooks) Session["DsBooks"];
}
else
{
this.sqlDataAda pter1.Fill(this .dsBooks1);
Session["DsBooks"] = dsBooks1;
this.DataGrid1. DataBind();
}
}
For information about maintaining state, see Web Forms State Management in
the Visual Studio documentation.
You can update the record normally. For an example, see Walkthrough: Using
a DataGrid Web Control to Read and Write Data in the Visual Studio
documentation. After updating the dataset, update the database, then
refresh the dataset. Be sure to save the refreshed dataset to Session state
again. Here is an example of an update handler:
' Visual Basic
Private Sub DataGrid1_Updat eCommand(ByVal source As Object, _
ByVal e As System.Web.UI.W ebControls.Data GridCommandEven tArgs) _
Handles DataGrid1.Updat eCommand
Dim dr As Dataset.BooksRo w
'Get a reference to row zero (where the row was inserted)
dr = Me.DsBooks1.Boo ks(0)
Dim tb As TextBox = CType(e.Item.Ce lls(2).Controls (0), TextBox)
dr.title = tb.Text
Dim cb As CheckBox = CType(e.Item.Ce lls(3).Controls (1), CheckBox)
dr.instock = cb.Checked
Me.SqlDataAdapt er1.Update(Me.D sBooks1)
DataGrid1.EditI temIndex = -1
'Refresh the dataset from the database
DsBooks1.Clear( )
Me.SqlDataAdapt er1.Fill(Me.DsB ooks1)
'Save the refreshed dataset in Session state agin
Session("DsBook s") = DsBooks1
DataGrid1.DataB ind()
End Sub
// C#
private void DataGrid1_Updat eCommand(object source,
System.Web.UI.W ebControls.Data GridCommandEven tArgs e)
{
dsBooks.BooksRo w dr;
//Get a reference to row zero (where the row was inserted)
dr = this.dsBooks1.B ooks[0];
TextBox tb1 = (TextBox) e.Item.Cells[2].Controls[0];
dr.title = tb1.Text;
CheckBox cb = (CheckBox) e.Item.Cells[3].Controls[1];
dr.instock = cb.Checked;
this.sqlDataAda pter1.Update(th is.dsBooks1);
DataGrid1.EditI temIndex = -1;
//Refresh the dataset from the database
dsBooks1.Clear( );
this.sqlDataAda pter1.Fill(this .dsBooks1);
//Save the refreshed dataset in Session state agin
Session["DsBooks"] = dsBooks1;
DataGrid1.DataB ind();
}
Thank you, Mike
Microsoft, ASP.NET Support Professional
Microsoft highly recommends to all of our customers that they visit the
http://www.microsoft.com/protect site and perform the three straightforward
steps listed to improve your computer’s security.
This posting is provided "AS IS", with no warranties, and confers no rights.
--------------------
Content-Class: urn:content-classes:message
From: "Jim Heavey" <an*******@disc ussions.microso ft.com>
Sender: "Jim Heavey" <an*******@disc ussions.microso ft.com>
Subject: DataGrid - Adding Rows
Date: Thu, 13 Nov 2003 05:46:54 -0800
Lines: 5
Message-ID: <0e************ *************** *@phx.gbl>
MIME-Version: 1.0
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
X-Newsreader: Microsoft CDO for Windows 2000
Thread-Index: AcOp7JlDGa9FRO6 BRD68/L+nUe3T9Q==
X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4910.0300
Newsgroups: microsoft.publi c.dotnet.framew ork.aspnet
Path: cpmsftngxa06.ph x.gbl
Xref: cpmsftngxa06.ph x.gbl microsoft.publi c.dotnet.framew ork.aspnet:1906 35
NNTP-Posting-Host: TK2MSFTNGXA09 10.40.1.161
X-Tomcat-NG: microsoft.publi c.dotnet.framew ork.aspnet
Trying to figure out the technique which should be used
to add rows to a datagrid. I am thinking that I would
want an "Add" button on the footer, but I am not quite
sure how to do that. Is that the best method? Do you
have a sample of how to do this?