By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
425,526 Members | 2,189 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 425,526 IT Pros & Developers. It's quick & easy.

Dynamic columns and NamingContainer

P: n/a
I dynamically add columns to DataGrid as described in MSDN
articles "Top Questions about the DataGrid Web Server Control"
and "Creating Web Server Control Templates Programmatically".
The columns are template based and all they use a same template
producer. In the edit mode (ListItemType.EditItem) the template
adds textbox and validator controls to a column as:

public void InstantiateIn(System.Web.UI.Control container)
{
TextBox tb = new TextBox();
tb.Text = "";
tb.ID = "MyTextBox";
container.Controls.Add(tb);
CompareValidator val = new CompareValidator();
val.ControlToValidate(tb.ID);
container.Controls.Add(val);
}

During run-time this method throws exception like "... multiple controls
have
same ID: MyTextBox...". Of course, if there was no need to use the
validator,
I probably will not touch ID of the textbox and leave it with a default
value (empty?).
But the validator requires this ID for its ControlToValidate property.
Any workarounds?

P.S. In above method, the "container" parameter is type of TableCell.
But its Parent and NamingContainer properties are undefined (I checked
it during debugging with QuickWatch). Why?
I expected that TableCell's Parent will be DataGridItem and NamingContainer
will be DataGridItem or DataGrid itself. I ask it because I want to
reference
a parent column from above InstantiateIn() method to create IDs based on
a column information (column index or something else).



Nov 27 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
The error you got means that you instantiated more than one column using the
same Template that contained more than one Textbox in the datagriditem with
the same ID. You can solve that by assigning the ID upon databinding:
1- Modify the InstaniateIn method to look like this:

TextBox tb = new TextBox();
container.Controls.Add(tb);
RequiredFieldValidator val = new RequiredFieldValidator ();
container.Controls.Add(val);
container.DataBinding += new EventHandler(ItemContainer_DataBinding);

2- Add another method like this:
void ItemContainer_DataBinding(object sender, EventArgs e)
{
TableCell td= (TableCell)sender; //gets the container
//gets the naming container that you wanted
DataGridItem dgItem = ((DataGridItem )td.NamingContainer );
//get the cell # within the tablerow
int cellNo=-0;
foreach (TableCell tc in dgItem.Cells)
{
if (tc == td) break;
cellNo++;
}
//the first control within the cell is the textbox
TextBox tb = td.Controls [0] as TextBox ;
//assign a unique ID for each cell within the same TableRow
tb.ID = "MyTextBox" + cellNo;
//the validator is the second control within the container
RequiredFieldValidator val = td.Controls[1] as RequiredFieldValidator;
//set the validator properties
val.ControlToValidate = tb.ID;
val.ErrorMessage = "Cannot leave blank";
//add a value to databind to the TextBox
tb.Text = ((DataRowView)dgItem.DataItem)[0].ToString ();
}
--
HTH,
Phillip Williams
http://www.societopia.net
http://www.webswapp.com
"Tumurbaatar S." wrote:
I dynamically add columns to DataGrid as described in MSDN
articles "Top Questions about the DataGrid Web Server Control"
and "Creating Web Server Control Templates Programmatically".
The columns are template based and all they use a same template
producer. In the edit mode (ListItemType.EditItem) the template
adds textbox and validator controls to a column as:

public void InstantiateIn(System.Web.UI.Control container)
{
TextBox tb = new TextBox();
tb.Text = "";
tb.ID = "MyTextBox";
container.Controls.Add(tb);
CompareValidator val = new CompareValidator();
val.ControlToValidate(tb.ID);
container.Controls.Add(val);
}

During run-time this method throws exception like "... multiple controls
have
same ID: MyTextBox...". Of course, if there was no need to use the
validator,
I probably will not touch ID of the textbox and leave it with a default
value (empty?).
But the validator requires this ID for its ControlToValidate property.
Any workarounds?

P.S. In above method, the "container" parameter is type of TableCell.
But its Parent and NamingContainer properties are undefined (I checked
it during debugging with QuickWatch). Why?
I expected that TableCell's Parent will be DataGridItem and NamingContainer
will be DataGridItem or DataGrid itself. I ask it because I want to
reference
a parent column from above InstantiateIn() method to create IDs based on
a column information (column index or something else).



Nov 27 '05 #2

P: n/a
Thank you!
I also found something like your recommendation.
My DataGrid already uses ItemCreated event so
I put there a code that sets these IDs.
Thank you again!

"Phillip Williams" <Ph**************@webswapp.com> wrote in message
news:5D**********************************@microsof t.com...
The error you got means that you instantiated more than one column using
the
same Template that contained more than one Textbox in the datagriditem
with
the same ID. You can solve that by assigning the ID upon databinding:
1- Modify the InstaniateIn method to look like this:

TextBox tb = new TextBox();
container.Controls.Add(tb);
RequiredFieldValidator val = new RequiredFieldValidator ();
container.Controls.Add(val);
container.DataBinding += new EventHandler(ItemContainer_DataBinding);

2- Add another method like this:
void ItemContainer_DataBinding(object sender, EventArgs e)
{
TableCell td= (TableCell)sender; //gets the container
//gets the naming container that you wanted
DataGridItem dgItem = ((DataGridItem )td.NamingContainer );
//get the cell # within the tablerow
int cellNo=-0;
foreach (TableCell tc in dgItem.Cells)
{
if (tc == td) break;
cellNo++;
}
//the first control within the cell is the textbox
TextBox tb = td.Controls [0] as TextBox ;
//assign a unique ID for each cell within the same TableRow
tb.ID = "MyTextBox" + cellNo;
//the validator is the second control within the container
RequiredFieldValidator val = td.Controls[1] as RequiredFieldValidator;
//set the validator properties
val.ControlToValidate = tb.ID;
val.ErrorMessage = "Cannot leave blank";
//add a value to databind to the TextBox
tb.Text = ((DataRowView)dgItem.DataItem)[0].ToString ();
}
--
HTH,
Phillip Williams
http://www.societopia.net
http://www.webswapp.com
"Tumurbaatar S." wrote:
I dynamically add columns to DataGrid as described in MSDN
articles "Top Questions about the DataGrid Web Server Control"
and "Creating Web Server Control Templates Programmatically".
The columns are template based and all they use a same template
producer. In the edit mode (ListItemType.EditItem) the template
adds textbox and validator controls to a column as:

public void InstantiateIn(System.Web.UI.Control container)
{
TextBox tb = new TextBox();
tb.Text = "";
tb.ID = "MyTextBox";
container.Controls.Add(tb);
CompareValidator val = new CompareValidator();
val.ControlToValidate(tb.ID);
container.Controls.Add(val);
}

During run-time this method throws exception like "... multiple controls
have
same ID: MyTextBox...". Of course, if there was no need to use the
validator,
I probably will not touch ID of the textbox and leave it with a default
value (empty?).
But the validator requires this ID for its ControlToValidate property.
Any workarounds?

P.S. In above method, the "container" parameter is type of TableCell.
But its Parent and NamingContainer properties are undefined (I checked
it during debugging with QuickWatch). Why?
I expected that TableCell's Parent will be DataGridItem and
NamingContainer
will be DataGridItem or DataGrid itself. I ask it because I want to
reference
a parent column from above InstantiateIn() method to create IDs based on
a column information (column index or something else).



Nov 27 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.