Create TextBox Controls in DataGrid that aren't DataBound

J

Jeff Cochand

Hi,
I want to create a DataGrid, in a WebForm, that contains a mix of
Label and TextBox Controls. The Text values of these Controls must be
settable (& retrievable) from the C# code behind.

The problem is that it seems very difficult to add TextBoxes to a
DataGrid, unless that DataGrid is DataBound.

My data is not coming from a database, so this is not a DataBound
case. The data used to set the Control.Text values is generated in
the C# code (specifically from the previous view of the aspx page).
The # of Items (rows) in the DataGrid is variable, based on the data.
The value of each column (Label.Text or TextBox.Text) is also data
dependent.

I figured out how to do this, but it seems overly complex. The
approach I used is to:
• Create a DataGrid, using templated columns (including asp:TextBox),
in the aspx file
• Generate the # of DataGrid Items (ie rows) needed, programmatically
in the cs file using a DataTable
• Set the values of the Templated Controls (for each row generated
above)
• Set AutoGenerateColumns=false in the aspx file, thus only displaying
the Templated Controls

I'm wondering if I might be missing a better way to do this. It sure
seems silly to have to generate this fake DataTable column & then not
display it. I also explored adding cells like
http://groups.google.com/groups?hl=...&selm=%24VRKaDnQCHA.224%40cpmsftngxa10&rnum=8,
but that seemed impossible to add fully customized rows of mixed Label
& TextBox Controls.

Here is the key code involved:

C# Code:
DataTable dt;
DataRow dr;
dt = new DataTable( "My DataTable" );
dt.Columns.Add( "columnAddedViaDataTable", Type.GetType(
"System.String" ));

// Add 3 rows
dr = dt.NewRow();
dr[ "columnAddedViaDataTable" ] = "Data Table cell value added
programmatically";
dt.Rows.Add( dr );

dr = dt.NewRow();
dr[ "columnAddedViaDataTable" ] = "Data Table cell value added
programmatically";
dt.Rows.Add( dr );

dr = dt.NewRow();
dr[ "columnAddedViaDataTable" ] = "Data Table cell value added
programmatically";
dt.Rows.Add( dr );

// Bind the DataTable to the aspx DataGrid
mydg.DataSource = dt;
mydg.DataBind();


// Here's what we really want to do...
// Set the values of the Templated Controls defined in the aspx file
// This way we can create TextBoxes in a DataGrid and set values of
all the controls
int nItems = 0;
foreach( DataGridItem dgi in mydg.Items )
{
// Since we put 3 rows into the DataTable above, and bound it,
// we'll loop 3 times here - once over each item
// That gives us the opportunity to set the value of each Templated
Control
nItems++; // Simply use nItems to fill with variable data
((Label)dgi.FindControl( "lbl1" )).Text = nItems.ToString();
((TextBox)dgi.FindControl( "txt1" )).Text = "TextBox #" +
nItems.ToString() + " value";
}


aspx Code:
<asp:DataGrid id="mydg" Runat="server" AutoGenerateColumns="False">
<Columns>
<asp:TemplateColumn HeaderText="Label 1">
<ItemTemplate>
<asp:Label ID="lbl1" Runat="server" />
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="TextBox 1">
<ItemTemplate>
<asp:TextBox ID="txt1" Runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>






Below are the full aspx and cs files that demonstrate this approach.

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace dgt
{
/// <summary>
/// Summary description for setTemplateControlsFromCsFile.
/// </summary>
public class setTemplateControlsFromCsFile : System.Web.UI.Page
{
protected System.Web.UI.WebControls.DataGrid mydg;

private void Page_Load(object sender, System.EventArgs e)
{
// A DataTable is created simply so rows can be added to it
// These rows will not be displayed, because
AutoGenerateColumns=false
// However, adding rows will generate columns for each Templated
Control in the aspx file
// After Binding, these columns can be filled with data
DataTable dt;
DataRow dr;
dt = new DataTable( "My DataTable" );
dt.Columns.Add( "columnAddedViaDataTable", Type.GetType(
"System.String" ));

// Add 3 rows
dr = dt.NewRow();
dr[ "columnAddedViaDataTable" ] = "Data Table cell value added
programmatically";
dt.Rows.Add( dr );

dr = dt.NewRow();
dr[ "columnAddedViaDataTable" ] = "Data Table cell value added
programmatically";
dt.Rows.Add( dr );

dr = dt.NewRow();
dr[ "columnAddedViaDataTable" ] = "Data Table cell value added
programmatically";
dt.Rows.Add( dr );

// Bind the DataTable to the aspx DataGrid
mydg.DataSource = dt;
mydg.DataBind();


// Here's what we really want to do...
// Set the values of the Templated Controls defined in the aspx
file
// This way we can create TextBoxes in a DataGrid and set values of
all the controls
int nItems = 0;
foreach( DataGridItem dgi in mydg.Items )
{
// Since we put 3 rows into the DataTable above, and bound it,
// we'll loop 3 times here - once over each item
// That gives us the opportunity to set the value of each
Templated Control
nItems++; // Simply use nItems to fill with variable data
((Label)dgi.FindControl( "lbl1" )).Text = nItems.ToString();
((TextBox)dgi.FindControl( "txt1" )).Text = "TextBox #" +
nItems.ToString() + " value";
}

}

#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion
}
}



<%@ Page language="c#"
Codebehind="setTemplateControlsFromCsFile.aspx.cs"
AutoEventWireup="false" Inherits="dgt.setTemplateControlsFromCsFile"
%>
<HTML>
<HEAD>
<title>setTemplateControlsFromCsFile</title>
</HEAD>
<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post" runat="server">
<!-- The whole goal here is to: -->
<!-- Display text boxes in a datagrid, and -->
<!-- Set the values of the Controls programmatically in the cs file
-->
<!-- This is easy, if you're using templated controls and binding
them to a db query. -->
<!-- It is also easy to programmatically set values of DataGrid
cells. -->
<!-- But it is very difficult to flexibly create text box controls
from a cs file. -->
<!-- TextBox Controls can be programmtically generated, but it is
difficult to create -->
<!-- a DataGrid that has several columns of Labels, followed by a
Column of TextBoxes, -->
<!-- followed by a few more Labels, etc. -->
<!-- So, the approach is: -->
<!-- Create a DataGrid, using templated columns (including
asp:TextBox), in the aspx file -->
<!-- Generate DataGrid Items (ie rows) programmatically in the cs
file -->
<!-- - Using a DataTable -->
<!-- - Adding one programmatically generated column -->
<!-- - Adding a row for each set of data to be displayed -->
<!-- Set AutoGenerateColumns=false in the aspx file -->
<!-- This will only show the templated columns, not the DataTable
column -->
<!-- The Control values for those templated columns will be set in
the cs file -->
<!-- Loop over the # of data sets (rows) to be displayed -->
<!-- Create that many rows in the DataTable -->
<!-- Bind that DataTable to the templated DataGrid -->
<!-- Loop again over the # of data sets (rows) to be displayed
-->
<!-- Get the values to be displayed for each set of data -->
<!-- Set those values in the column for each templated Control
-->
<!-- -->
<!-- AutoGenerateColumns=false doesn't show the DataTable columns
that are -->
<!-- attempted to be added programmatically in the cs file -->
<!-- It just shows the templated columns -->
<!-- Set to true, it shows both the DataTable columns & the
templated columns -->
<asp:DataGrid id="mydg" Runat="server" AutoGenerateColumns="False">
<Columns>
<asp:TemplateColumn HeaderText="Label 1">
<ItemTemplate>
<asp:Label ID="lbl1" Runat="server" />
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="TextBox 1">
<ItemTemplate>
<asp:TextBox ID="txt1" Runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>
</form>
</body>
</HTML>



It probably won't be easily visible in the newsgroup posting, but an
example of what I want to create is below. Qty Needed, Target Price,
& Required By are TextBox Controls.
Part # Description Qty Qty Needed Mfg Price Target Price DC Lead
Time Vendor Updated Required By
1 widget #1 1 Mfg - 1 $1 DC763 2 days ABC Inc. 9/24/04
2 widget #2 2 Mfg - 2 $2 DC763 2 days ABC Inc. 9/24/04
3 widget #3 3 Mfg - 3 $3 DC763 2 days ABC Inc. 9/24/04
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top