-----Original Message-----
You are most welcome, Krista.
To the problem at hand:
You have 3 basic options available to you. You can either create the columns
for the data grid in the HTML/ASPX code by using tags (or the visual
designer, which isn't all that bad. Kind of nice to use, actually
), you
can have the columns created in the Page_Load event (by placing the column
generating code before the check for IsPostBack), or in the OnInit() method.
I would dare say that creating the columns in the HTML code is by far the
easiest, but it is also the worst when it comes to maintenance.
Try moving the column generating code to the Page_Load first and see what
happens. Make sure that the columns are created before you check for post
back. I think you should get different results. Sorry if I steered you down
the wrong path earlier... Hindsight is always 20/20... lol
HTH,
Kyril
Once again Kyril, Thank You for your help. I tried
exactly what you told me with the loop, but the
e.Item.Cells(1).Controls does not return any controls. I
checked the count on this line (e.Item.Cells
(1).Controls.Count) and it gave me 0, but after I do
BindData() (without trying to retrieve the value of the
TextBox), it creates the datagrid fine without any errors
and the same line returns the number of columns that I
programatically added. It seems as if I need to BindData
before I try to retrieve the textbox values, which from
my understanding should not be the case. Is it possible
that I need to create my columns of my DataGrid in a
different place? Becuase right now my created datagrid
columns disapear until I call BindData again. But I would
probably need to do that 2 times on each edit (BindData
before retrieving TextBox values, and the BindData after
modifying the DataTable with the TextBox values). Does
that make sense? Or am I completly off track?
Thank You for your help and time.
Merci,
Krista Lemieux
-----Original Message-----
Hi Krista,
Never assume that the TextBox in EditMode is at the
beginning of the
Controls collection.
Often times, especially if there
is text in the cell
or it is a TemplateColumn, the text box may be at
position 1 or further down
the chain.
There are two ways that you can accomplish what you want
to do. The first
would be to iterate through the Control collection of
the cell and test each
control to see if it is a textbox. Otherwise, you can
use the FindControl
method to locate the textbox by ID.
Something like this: (forgive me for doing this in C#,
my VB.NET is really
rusty!)
<pseudo-code>
//This code snippet loops through the cell's controls
//collection and tests each control to see if it is a
text box
foreach(Control c in e.Item.Cells[1].Controls)
{
if(c is TextBox)
{
//grab the value of this text box...
string text = ((TextBox)c).Text;
}
}
//This is the FindControl method at work
TextBox tempText = (TextBox)dataGrid.FindControl
("TextBoxName");
if(tempText != null)
{
//do something here...
}
In VB.NET, I think it would be
'This is the same loop as above.
For Each c In e.Item.Cells[1].Controls
If c Is TextBox Then
Dim text As String = (CType(c, TextBox)).Text
End If
Next
'This is the FindControl method at work
Dim tempText as TextBox = CType(dataGrid.FindControl
("TextBoxName"),
TextBox)
If tempText IsNot Nothing Then
'Do something here
End if
</pseudo-code>
You could loop through all the cells this way and grab
all the text box
values or you could just call FindControl for each
textbox value that you
need.
HTH,
Kyril
message
Thank you for your help Kyril. I tried the code (your
pseudo) on my page with my datagrid. Everything worked
great except one thing... I tried combining your code
with a code that I saw in a book, so that I can edit a
row and update it. Basically when I click the Edit link
it shows the selected row in the edit mode (textboxes),
but when I try to update my changes (by clicking the
Update Link) it gives me an Index out of bounds error
in
the Update button function. It is as if the columns no
longer exist. Like in the example I'm trying to read
the
value from the textbox by getting the CType
(e.Item.Cells
(1).Controls(0), TextBox).Text, and then after
retrieving
the values I'm caling the BindData function (all of
this
is in the Update button function). Am I doing something
wrong that I cannot access the values of the textboxes?
Thank you very much for the help.
Merci,
Krista Lemieux
-----Original Message-----
Hi Krista,
Adding columns to the datagrid programmatically is
actually pretty easy to
do. Have you looked at the DataGrid's
AutoGenerateColumns property? It will
dynamically create columns based on the data source
that
you use. It's a
nice feature, but does not give much in terms of
customization or control.
To dynamically add columns, what you should do is
something like below:
<pseudo-code>
private void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack) { BindData(); }
}
private void BindData()
{
//here we will add two columns to our data grid.
//assume the name of the grid is dg
ButtonColumn btnCol = new ButtonColumn();
btnCol.ButtonType = ButtonColumnType.LinkButton;
btnCol.CommandName = "Select";
btnCol.HeaderText = "Select";
btnCol.Text = "Select Item";
dg.Columns.Add(btnCol);
BoundColumn boundCol = new BoundColumn();
boundCol.DataField = "Author";
boundCol.HeaderText = "Authors";
dg.Columns.Add(boundCol);
dg.DataKeyField = "AuthorID";
dg.DataSource = authorsDataTable;
dg.DataBind();
}
</pseudo-code>
Now, this will fire only on the first page load because
of the
"if(!Page.IsPostBack)". What you will do now is hook up
the datagrid events
so that you can interact with the grid. To trap the
click of one of the link
buttons for instance, you can use one of two events in
the data grid. Either
the ItemCommand event or the SelectedIndexChanged
event.
All you have to do
is make sure that anything in your page that will
trigger a post back (a
button or a drop down list changing) calls the BindData
() method to rebuild
and rebind the data grid. Now, there are a couple of
other places that you
can put the column creation code. You can put it in the
Page_Load event
handler, before the check for a postback. You can also
place it in the
overridden OnInit method.
Like Michael said, given time, you'll pick up the data
grid in no time. It
is one of the most flexible (and most complicated)
controls in the .NET
Framework, but it pays off.
HTH,
Kyril
message
Thanks for the quick reply Michael
You mentioned to use DataGrid. I'm experimenting with
it
currently, but I had a hard time adding columns to it
programatically (or dynamically) so I dropped it. I
don't
remember what the exact problem was, but I think it
was
something on each postback they waren't appearing
correcly or just not being re-added. Is there a
specific
place where I should add the dynamic columns so I
have
no
problems on post back. I mean should I add them in
the
Init section, or the Page_Load (since I can't, or
don't
want to put my while loop creating this in the aspx
file).
Thank You so much in advance for help.
Merci,
Krista Lemieux
-----Original Message-----
message
...How does this information get preserved?
ViewState!
Would I create the Table
(not the DataTable) in the Page_Load and bind it
only
once (not on
each postback)??? How does that work.
Check out the DataGrid control, you can easily bind
the
information in a datatable to it. No need to create
your
own table. You would bind this initially when the
page
first loads, and if something every changed in it
(selected a record, went to the next page of results,
sort, etc) you would rebind the contents to reflect
the
new changes.
It'll make sense if you work with it enough, trust me
--Michael
.
.
.
.