I need some help in rendering a dynamic gridview. Using the source code below, I can add the grid to the page and it generates one row for each entry in the datasource. The problem is that the controls only appears in the last row. If I add another entry to the datasource, I get one more row in the Gridview but only the last is showing the controls that I've added using the ItemTemplate. When I debug the solution I can see that it instatiates a new ItemTemplate foreach collumn and that it adds all the controls, but after the databinding of the grid, all the cells are empty, except the ones of the last row.
Please help if you can. Thanks
private void BuildGridInterface()
{
TBL_PARAM_01 xpto = new TBL_PARAM_01();
GridView grid = new GridView();
grid.ID = "grd";
grid.AutoGenerateColumns = false;
grid.ShowHeader = true;
PropertyInfo[] props = xpto.GetType().GetProperties();
foreach (PropertyInfo info in props)
{
TemplateField field = new TemplateField();
object[] attributes = info.GetCustomAttributes(true);
var att = attributes.SingleOrDefault(a => a.GetType() == typeof(Domain));
WebControl control;
if (att != null)
{
control = new DropDownList();
control.ID = "drp" + info.Name;
((DropDownList)control).Items.Add(new ListItem() { Text = "XXXXX", Value = "1" });
((DropDownList)control).Items.Add(new ListItem() { Text = "XXXX2", Value = "2" });
((DropDownList)control).Items.Add(new ListItem() { Text = "XXXX3", Value = "3" });
((DropDownList)control).Items.Add(new ListItem() { Text = "XXXX4", Value = "4" });
((DropDownList)control).Items.Add(new ListItem() { Text = "XXXX5", Value = "5" });
((DropDownList)control).Items.Add(new ListItem() { Text = "XXXX6", Value = "6" });
}
else
{
control = new TextBox();
control.ID = "txt" + info.Name;
}
field.ItemTemplate = new ItemTemplate(control, false, info.Name);
field.HeaderText = ((MatrixFieldLabel)attributes.Single(a => a.GetType() == typeof(MatrixFieldLabel))).Value;
grid.Columns.Add(field);
}
FillGrid(grid);
placer.Controls.Add(grid);
}
public class ItemTemplate : ITemplate
{
WebControl Control { get; set; }
bool Enabled { get; set; }
string ColumName { get; set; }
public ItemTemplate(WebControl control, bool enabled, string columname)
{
this.Control = control;
this.Enabled = enabled;
this.ColumName = columname;
control.DataBinding += new EventHandler(Control_DataBinding);
}
public void InstantiateIn(Control container)
{
((WebControl)container).Enabled = Enabled;
container.Controls.Add(this.Control);
}
void Control_DataBinding(object sender, EventArgs e)
{
GridViewRow container = (GridViewRow)((Control)sender).NamingContainer;
object dataValue = DataBinder.Eval(container.DataItem, this.ColumName);
if (sender.GetType() == typeof(TextBox))
((TextBox)sender).Text = dataValue.ToString();
else if (sender.GetType() == typeof(DropDownList))
((DropDownList)sender).SelectedValue = dataValue.ToString();
}
private void FillGrid(GridView target)
{
List<TBL_PARAM_01> list = new List<TBL_PARAM_01>();
list.Add(new TBL_PARAM_01() { IDEntityRecordProduct = 1, IDEntityRecordX = 2, Output = "XPTO 3" });
list.Add(new TBL_PARAM_01() { IDEntityRecordProduct = 2, IDEntityRecordX = 3, Output = "XPTO 4" });
list.Add(new TBL_PARAM_01() { IDEntityRecordProduct = 3, IDEntityRecordX = 4, Output = "XPTO 5" });
list.Add(new TBL_PARAM_01() { IDEntityRecordProduct = 4, IDEntityRecordX = 5, Output = "XPTO 6" });
list.Add(new TBL_PARAM_01() { IDEntityRecordProduct = 5, IDEntityRecordX = 6, Output = "XPTO 7" });
target.DataSource = list;
target.DataBind();
}
}
Problem solved. I've had to rewrite the method InstantiateIn of my ItemTemplate class. Thanks.