Hi,
we have tried to build gridview with dynamic columns based the data source using the template fields in asp.net through code behind because the no.of columns to display may vary each month.
For that, to implement we have developed one class "DynamicTemplate" which implements the "ITemplate" interface. In that template fields i have inserted the "LinkButton" in each cell and when i click that cell link button i need to show the one Popup with selected cell value.
For that i have created one Default.asxp page and wrote the following.
For Detailed Sample Please download from this link [
^]
public partial class Default : System.Web.UI.Page
{
DataTable dt;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
GenateGridView();
}
private void GenateGridView()
{
TemplateField tempField;
DynamicTemplate dynTempItem;
LinkButton lnkButton;
Label label;
GridView gvDynamicArticle = new GridView();
gvDynamicArticle.Width = Unit.Pixel(500);
gvDynamicArticle.BorderWidth = Unit.Pixel(0);
gvDynamicArticle.Caption = "<div>Default Grid</div>";
gvDynamicArticle.AutoGenerateColumns = false;
DataTable data = getBindingData();
for (int i = 0; i < data.Columns.Count; i++)
{
tempField = new TemplateField();
dynTempItem = new DynamicTemplate(ListItemType.AlternatingItem);
lnkButton = new LinkButton();
lnkButton.ID = string.Format("lnkButton{0}", i);
lnkButton.Visible = true;
string ColumnValue = data.Columns[i].ColumnName;
tempField.HeaderText = ColumnValue;
if (ColumnValue == "EmpName")
{
label = new Label();
label.ID = string.Format("Label{0}", i);
dynTempItem.AddControl(label, "Text", ColumnValue);
label.Width = 100;
}
else
{
dynTempItem.AddControl(lnkButton, "Text", ColumnValue);
lnkButton.Click += lnkButton_Click;
}
tempField.ItemTemplate = dynTempItem;
gvDynamicArticle.Columns.Add(tempField);
}
gvDynamicArticle.DataSource = data;
gvDynamicArticle.DataBind();
divContainer.Controls.Add(gvDynamicArticle);
}
void lnkButton_Click(object sender, EventArgs e)
{
ClientScript.RegisterStartupScript(this.GetType(), "alert", "alert('cell clicked')");
}
private DataTable getBindingData()
{
dt = new DataTable();
dt.Columns.Add(new DataColumn("EmpName"));
dt.Columns.Add(new DataColumn("Monday"));
dt.Columns.Add(new DataColumn("TuesDay"));
dt.Columns.Add(new DataColumn("WednesDay"));
dt.Columns.Add(new DataColumn("ThursDay"));
dt.Rows.Add("EmpOne", "p", "p", "p", "a");
dt.Rows.Add("EmpTwo", "p", "a", "p", "p");
dt.Rows.Add("EmpThree", "p", "p", "p", "a");
dt.Rows.Add("EmpFour", "p", "a", "p", "p");
dt.Rows.Add("EmpFive", "p", "p", "p", "a");
dt.Rows.Add("EmpSix", "a", "p", "p", "p");
return dt;
}
}
and corresponding DynamicTemplate class is
public class DynamicTemplate : System.Web.UI.ITemplate
{
System.Web.UI.WebControls.ListItemType templateType;
System.Collections.Hashtable htControls = new System.Collections.Hashtable();
System.Collections.Hashtable htBindPropertiesNames = new System.Collections.Hashtable();
System.Collections.Hashtable htBindExpression = new System.Collections.Hashtable();
public DynamicTemplate(System.Web.UI.WebControls.ListItemType type)
{
templateType = type;
}
public void AddControl(WebControl wbControl, String BindPropertyName, String BindExpression)
{
htControls.Add(htControls.Count, wbControl);
htBindPropertiesNames.Add(htBindPropertiesNames.Count, BindPropertyName);
htBindExpression.Add(htBindExpression.Count, BindExpression);
}
public void InstantiateIn(System.Web.UI.Control container)
{
PlaceHolder ph = new PlaceHolder();
for (int i = 0; i < htControls.Count; i++)
{
Control cntrl = CloneControl((Control)htControls[i]);
switch (templateType)
{
case ListItemType.Header:
break;
case ListItemType.Item:
ph.Controls.Add(cntrl);
break;
case ListItemType.AlternatingItem:
ph.Controls.Add(cntrl);
ph.DataBinding += new EventHandler(Item_DataBinding);
break;
case ListItemType.Footer:
break;
}
}
ph.DataBinding += new EventHandler(Item_DataBinding);
container.Controls.Add(ph);
}
public void Item_DataBinding(object sender, System.EventArgs e)
{
PlaceHolder ph = (PlaceHolder)sender;
GridViewRow ri = (GridViewRow)ph.NamingContainer;
for (int i = 0; i < htControls.Count; i++)
{
if (htBindPropertiesNames[i].ToString().Length > 0)
{
Control tmpCtrl = (Control)htControls[i];
String item1Value = (String)DataBinder.Eval(ri.DataItem, htBindExpression[i].ToString());
Control ctrl = ph.FindControl(tmpCtrl.ID);
Type t = ctrl.GetType();
System.Reflection.PropertyInfo pi = t.GetProperty(htBindPropertiesNames[i].ToString());
pi.SetValue(ctrl, item1Value.ToString(), null);
}
}
}
private Control CloneControl(System.Web.UI.Control src_ctl)
{
Type t = src_ctl.GetType();
Object obj = Activator.CreateInstance(t);
Control dst_ctl = (Control)obj;
PropertyDescriptorCollection src_pdc = TypeDescriptor.GetProperties(src_ctl);
PropertyDescriptorCollection dst_pdc = TypeDescriptor.GetProperties(dst_ctl);
for (int i = 0; i < src_pdc.Count; i++)
{
if (src_pdc[i].Attributes.Contains(DesignerSerializationVisibilityAttribute.Content))
{
object collection_val = src_pdc[i].GetValue(src_ctl);
if ((collection_val is IList) == true)
{
foreach (object child in (IList)collection_val)
{
Control new_child = CloneControl(child as Control);
object dst_collection_val = dst_pdc[i].GetValue(dst_ctl);
((IList)dst_collection_val).Add(new_child);
}
}
}
else
{
dst_pdc[src_pdc[i].Name].SetValue(dst_ctl, src_pdc[i].GetValue(src_ctl));
}
}
return dst_ctl;
}
}
Here the Data showing in gridview is fine
Here the Issues are
when i click on the linkButton the page reloads and no grid is displaying after the postback.
and for LinkButton the "Click Event" is not firing.
Please provide me the help full information/Sample to show the modal window when we click on the linkButton of the gridview.