I would like somebody to help me to solve the following issue.
I have a gridview, where the fields are created dynamically from codebehind.
I would like to create with the same way(dynamically) a templateField which, if it is possible, to hold in it two button controls, having also and commandName.
To be more clear:
Headers-->> First Name, LastName, Print(Daily/Invoices)
Results -->> FooFName, FooLName, Daily | Invoice
The bold one text is what I am looking for.
I am posting also the methods and the way I use them to create the fields.
CreateBoundField(BillingSummaryGV, "Book_Date", "Date", "{0:dd/MM/yyyy}");
CreateButtonField(BillingSummaryGV, "Print", "Print(Daily)", ButtonType.Link,"");
BillingSummaryGV.DataSource = billingSummaries;
BillingSummaryGV.DataBind();
protected void CreateBoundField(GridView gv, string dataField, string headerText, string arrFormatingString) {
var bf = new BoundField {
DataField = dataField,
DataFormatString = arrFormatingString,
HeaderText = headerText
};
gv.Columns.Add(bf);
}
private void CreateButtonField(GridView gv, string text, string headerText, ButtonType buttonType, string commandName) {
var bfPrint = new ButtonField() {
ButtonType = buttonType,
Text = text,
HeaderText = headerText,
Visible = true,
CommandName = commandName
};
gv.Columns.Add(bfPrint);
}
I would appreciate any reply
thanks
You have to create a template class that implements ITemplate. See this example from MSDN. The code below extends my answer to this question to add a template column that displays Title|Author.
Markup:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false"
OnRowCommand="GridView1_RowCommand"
OnRowEditing="GridView1_RowEditing"/>
Code:
protected void Page_Load(object sender, EventArgs e)
{
BindGridView();
}
private DataTable GetBooksDataTable()
{
var dt = new DataTable();
dt.Columns.Add("ID", typeof(int));
dt.Columns.Add("Title", typeof(string));
dt.Columns.Add("Author", typeof(string));
for (int index = 0; index < 10; index++)
{
dt.Rows.Add(index, "Title" + index, "Author" + index);
}
return dt;
}
private void BindGridView()
{
var dt = GetBooksDataTable();
GridView1.Columns.Clear();
GridView1.ShowFooter = true;
var cf = new CommandField();
cf.HeaderText = "Action";
cf.ShowEditButton = true;
GridView1.Columns.Add(cf);
for (int index = 0; index < dt.Columns.Count; index++)
{
var boundField = new BoundField();
boundField.DataField = dt.Columns[index].ColumnName;
boundField.HeaderText = dt.Columns[index].ColumnName;
GridView1.Columns.Add(boundField);
}
CreateCustomTemplateField(GridView1, "Title|Author");
GridView1.DataSource = dt;
GridView1.DataBind();
var footer = GridView1.FooterRow;
var b = new LinkButton();
b.Text = "Add New";
b.CommandName = "Add New";
footer.Cells[0].Controls.Add(b);
for (int index = 1; index < dt.Columns.Count + 1; index++)
{
var tb = new TextBox();
footer.Cells[index].Controls.Add(tb);
}
}
private void CreateCustomTemplateField(GridView gv, string headerText)
{
var customField = new TemplateField();
customField.HeaderTemplate = new CustomTemplate(DataControlRowType.Header, headerText);
customField.ItemTemplate = new CustomTemplate(DataControlRowType.DataRow, headerText);
gv.Columns.Add(customField);
}
public class CustomTemplate : ITemplate
{
private DataControlRowType _rowType;
private string _headerText;
public CustomTemplate(DataControlRowType rowType, string headerText)
{
_rowType = rowType;
_headerText = headerText;
}
public void InstantiateIn(Control container)
{
switch (_rowType)
{
case DataControlRowType.Header:
var header = new Literal();
header.Text = _headerText;
container.Controls.Add(header);
break;
case DataControlRowType.DataRow:
var data = new Literal();
data.DataBinding += DataRowLiteral_DataBinding;
container.Controls.Add(data);
break;
}
}
private void DataRowLiteral_DataBinding(object sender, EventArgs e)
{
var data = (Literal)sender;
var row = (GridViewRow)data.NamingContainer;
data.Text = DataBinder.Eval(row.DataItem, "Title") + "|" + DataBinder.Eval(row.DataItem, "Author");
}
}
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
Literal1.Text = e.CommandName;
}
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
Literal1.Text = "Editing row index " + e.NewEditIndex.ToString();
}
Related
currently this method is displaying in a gridview2 just the first column of the rows checked in gridview1 checkboxes but i need to display all of the columns exactly as gridview1, so how do i do it?
protected void Button1_Click2(object sender, EventArgs e)
{
List<string> lista = new List<string>();
for (int i = 0; i < GridView1.Rows.Count; i++)
{
CheckBox chbox = GridView1.Rows[i].Cells[0].FindControl("chk") as CheckBox;
if (chbox.Checked == true)
{
lista.Add("'" + GridView1.Rows[i].Cells[1].Text + "'");
}
}
DataTable dt = new DataTable();
GridView2.DataSource = lista;
GridView2.DataBind();
}
code to of your button will be below
protected void Button1_Click2(object sender, EventArgs e)
{
List<CopyGrid> lista = new List<CopyGrid>();
for (int i = 0; i < GridView1.Rows.Count; i++)
{
CheckBox chbox = GridView1.Rows[i].Cells[0].FindControl("chk") as CheckBox;
if (chbox.Checked == true)
{
CopyGrid content = new CopyGrid();
content.Name = GridView1.Rows[i].Cells[1].Text;
content.Email = GridView1.Rows[i].Cells[2].Text;
content.City = GridView1.Rows[i].Cells[3].Text;
content.PostCode = GridView1.Rows[i].Cells[4].Text;
lista.Add(content);
}
}
// DataTable dt = new DataTable();
GridView2.DataSource = lista;
GridView2.DataBind();
}
also create one class that will store details of gridview1
public class CopyGrid
{
public string Name;
public string Email;
public string City;
public string PostCode;
}
This is just sample code you have to implement your own code.
I have a DropDownList which has a list of tables. Under it there is GridView. Based on the table selected from the drop down list box, I will populate the GridView dynamically. Since the tables could have different column names, I need to create the template field for the GridView dynamically.
Following is my bind method. I have two problems:
I couldn’t wrap the binding part in if (!IsPostBack) since the GridView is populated based on the selection of the DropDownList, so everytime I change the selection, the columns will be duplicated.
And I don’t have any data, I think I need to set ItemTemplate of the tField (TemplateField), but how do I do that?
My bind method
private void BindGridView()
{
DataSet ds = new DataSet();
try
{
ds = …
if (ds.Tables.Count > 0)
{
foreach (DataColumn dc in ds.Tables[0].Columns)
{
TemplateField tField = new TemplateField();
tField.HeaderText = dc.ColumnName;
GridView2.Columns.Add(tField);
}
GridView2.DataSource = ds.Tables[0];
GridView2.DataBind();
}
else
{
…
}
}
catch (Exception ex)
{
…
}
}
There are various steps that should be taken care of:
STEP I::
Create a class inheriting the ITemplate interface. Override the method InstantiateIn() of the ITemplate interface.
STEP II:
Define a constructor for your class that takes a ListItemType object as its parameter.
STEP III::
If the Control being added to the container's ControlCollection has to be bound to some DataSource Column, then register the
handler for the OnDataBinding event. When the event occurs, retrieve the text from the data source and assign it to your control. For Example, hyprLnk_DataBinding event is defined for Binding Data to your controls created inside ItemTemplate.
public class TemplateGenerator : ITemplate // Class inheriting ITemplate
{
ListItemType type;
string columnName;
public TemplateGenerator(ListItemType t, string cN)
{
type = t;
columnName= cN;
}
// Override InstantiateIn() method
void ITemplate.InstantiateIn(System.Web.UI.Control container)
{
switch (type)
{
case ListItemType.Item:
HyperLink hyprLnk = new HyperLink();
hyprLnk.Target = "_blank"; //Optional.
hyprLnk.DataBinding+=new EventHandler(hyprLnk_DataBinding);
container.Controls.Add(hyprLnk);
break;
}
}
// The DataBinding event of your controls
void hyprLnk_DataBinding(object sender, EventArgs e)
{
HyperLink hyprlnk = (HyperLink)sender;
GridViewRow container = (GridViewRow)hyprlnk.NamingContainer;
object bindValue = DataBinder.Eval(container.DataItem,columnName);
// Adding check in case Column allows null values
if (bindValue != DBNull.Value)
{
hyprlnk.Text = bindValue.ToString();
hyprlnk.NavigateUrl = "http://www.google.com";
}
}
}
That's all. Above was just a sample to create ItemTemplate dynamically for GridView and add controls to the Item Template.
Now, Below is the function that will actually carry out the calls to create Template Columns dynamically. You can call this function when required for e.g. from your DropDownList event Handler.
protected void GenerateGridViewColumnsDynamically()
{
// Create the TemplateField
TemplateField firstName = new TemplateField();
firstName.HeaderText = "First_Name";
firstName.ItemTemplate = new TemplateGenerator(ListItemType.Item, "FirstName");
// Showing boundField example just for more context
BoundField lastName = new BoundField();
lastName.DataField = "LastName";
lastName.HeaderText = "Last_Name";
// Add the Columns now
MyGridView.Columns.Add(firstName);
MyGridView.Columns.Add(lastName);
}
NOTE:: FirstName and LastName are the Columns whose Names are passed to the constructor of your custom class: TemplateGenerator.
I have done the same functionality as below with custom paging(using storedProc) for 100+ million records in many tables, update, delete and insert also:
CREATE PROCEDURE [dbo].[sp_Mk]
#PageIndex INT,
#PageSize INT,
#tableName nvarchar(255),
#totalRow INT Output
AS
BEGIN
DECLARE #sql NVARCHAR(MAX)
Declare #anotherSql NVARCHAR(1000)
DECLARE #ParamDefinition NVARCHAR(500)
--DECLARE #totalRow INT
Set #sql = 'WITH TempResult AS( SELECT * FROM '+#tableName+'), TempCount AS ( SELECT COUNT(*) AS MaxRows FROM TempResult )
SELECT * FROM TempResult, TempCount ORDER BY (Select Null)
OFFSET '+CONVERT(VARCHAR(20),(#PageIndex-1)*#PageSize) +' ROWS FETCH NEXT '+CONVERT(VARCHAR(20),#PageSize)+' ROWS ONLY'
PRINT #SQL
EXECUTE sp_executesql #SQL
Set #anotherSql=N'SELECT COUNT(*) as totalRow FROM '+#tableName
SET #ParamDefinition = N'#totalRowOutPut INT OUTPUT'
--PRINT #anotherSql
Execute sp_executesql #anotherSql,
#ParamDefinition,
--#tableNameInput=#tableName,
#totalRowOutPut=#totalRow OUTPUT
End
<asp:GridView CssClass="table-striped header-fixed" ID="grdDynamic" runat="server" AutoGenerateColumns="True" ShowHeaderWhenEmpty="true" AutoGenerateEditButton="true" AutoGenerateDeleteButton="true"
OnRowEditing="OnRowEditing_grdDynamic" OnRowUpdating="OnRowUpdating_grdDynamic" OnRowCancelingEdit="OnRowCancelingEdit_grdDynamic" OnRowDeleting="OnRowDeleting_grdDynamic" OnRowDataBound="OnRowDataBound_grdDynamic">
</asp:GridView><br/>
<asp:linkbutton id="AddButton" runat="server" commandname="Add" text="Insert: " OnClick="AddNewButton_Click" /><br/>
<asp:Repeater ID="rptPager" runat="server">
<ItemTemplate>
<asp:LinkButton ID="lnkPage" CssClass="pagination-ys" runat="server" Text = '<%#Eval("Text") %>' CommandArgument = '<%# Eval("Value") %>' Enabled = '<%# Eval("Enabled") %>' OnClick = "Page_Changed"></asp:LinkButton>
</ItemTemplate>
</asp:Repeater><asp:HiddenField runat="server" id="hdnPageIndex" Value="1"></asp:HiddenField>
SqlConnectionStringBuilder builder;
int pageSize = 100;
protected void Page_Load(object sender, EventArgs e)
{
builder = new SqlConnectionStringBuilder(connectionString);
if (!IsPostBack)
{
using (SqlConnection connObj = new SqlConnection(connectionString))
{
connObj.Open();
using (SqlDataAdapter adapter = new SqlDataAdapter("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_CATALOG='" + builder.InitialCatalog + "' AND TABLE_NAME Not In('AspNetUsers') Order By TABLE_NAME", connObj))
{
DataSet ds = new DataSet();
adapter.Fill(ds);
ddlTableNames.DataSource = ds;
ddlTableNames.DataBind();
ddlTableNames.Items.Insert(0, new ListItem("Select Table", String.Empty));
}
}
}
//}
//else if(ddlTableNames.Visible) ddlTableNames.Visible = false;
}
protected void ddlTableNames_SelectedIndexChanged(object sender, EventArgs e)
{
if (ddlTableNames.SelectedValue != "")
{
grdDynamic.Visible = true;
this.BindGrid(ddlTableNames.SelectedValue, Convert.ToInt32(hdnPageIndex.Value));
}
else if (grdDynamic.Visible == true) grdDynamic.Visible = false;
}
private void BindGrid(string selectedTable, int pageIndex, bool addNewRow=false)
{
using (SqlConnection connObj = new SqlConnection(connectionString))
{
using (SqlCommand cmd = new SqlCommand("sp_Mk", connObj))
{
int recordCount=0;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#PageIndex", pageIndex);
cmd.Parameters.AddWithValue("#PageSize", pageSize);
cmd.Parameters.AddWithValue("#tableName", ddlTableNames.SelectedValue);
SqlParameter totalRow = new SqlParameter("#totalRow", SqlDbType.Int, 4);
totalRow.Direction = ParameterDirection.Output;
cmd.Parameters.Add(totalRow);
connObj.Open();
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
adapter.Fill(ds);
grdDynamic.DataSource = ds.Tables[0];
if (addNewRow) ds.Tables[0].Rows.Add();
recordCount = Convert.ToInt32(ds.Tables[1].Rows[0].ItemArray[0]);
grdDynamic.DataBind();
connObj.Close();
if (totalRow.Value != DBNull.Value)
{
}
this.PopulatePager(recordCount, pageIndex);
}
}
}
private void PopulatePager(int recordCount, int currentPage)
{
double dblPageCount = (double)((decimal)recordCount / pageSize);
int pageCount = (int)Math.Ceiling(dblPageCount);
List<ListItem> pages = new List<ListItem>();
if (pageCount > 0)
{
pages.Add(new ListItem("First", "1", currentPage > 1));
for (int i = 1; i <= pageCount; i++)
{
ListItem item=new ListItem(i.ToString(), i.ToString(), i != currentPage);
if (i == currentPage) item.Attributes.Add("style", "color:red;");
pages.Add(item);
}
pages.Add(new ListItem("Last", pageCount.ToString(), currentPage < pageCount));
}
rptPager.DataSource = pages;
rptPager.DataBind();
}
protected void Page_Changed(object sender, EventArgs e)
{
int pageIndex = int.Parse((sender as LinkButton).CommandArgument);
hdnPageIndex.Value = pageIndex.ToString();
this.BindGrid(ddlTableNames.SelectedValue, pageIndex);
}
protected void OnRowEditing_grdDynamic(object sender, GridViewEditEventArgs e)
{
grdDynamic.EditIndex = e.NewEditIndex;
this.BindGrid(ddlTableNames.SelectedValue, Convert.ToInt32(hdnPageIndex.Value));
}
protected void OnRowUpdating_grdDynamic(object sender, GridViewUpdateEventArgs e)
{
GridViewRow row = grdDynamic.Rows[e.RowIndex];
string updateStatement = string.Empty;
for (int x = 0; x < row.Cells.Count; x++) updateStatement = updateStatement + grdDynamic.DataKeys[e.RowIndex].Values[x] + " = " + grdDynamic.DataKeys[e.RowIndex].Values[x] + ", ";
//int recordId = Convert.ToInt32(grdDynamic.DataKeys[e.RowIndex].Values[0]);
using (SqlConnection con = new SqlConnection(connectionString))
{
//using (SqlCommand cmd = new SqlCommand("UPDATE "+selectedTable"+ SET Name = #Name, Country = #Country WHERE CustomerId = #CustomerId"))
{
cmd.Connection = con;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
}
grdDynamic.EditIndex = -1;
this.BindGrid(ddlTableNames.SelectedValue, Convert.ToInt32(hdnPageIndex.Value));
}
protected void OnRowCancelingEdit_grdDynamic(object sender, EventArgs e)
{
grdDynamic.EditIndex = -1;
this.BindGrid(ddlTableNames.SelectedValue, Convert.ToInt32(hdnPageIndex.Value));
}
protected void OnRowDeleting_grdDynamic(object sender, GridViewDeleteEventArgs e)
{
int recordId = Convert.ToInt32(grdDynamic.DataKeys[e.RowIndex].Values[0]);
using (SqlConnection con = new SqlConnection(connectionString))
{
using (SqlCommand cmd = new SqlCommand("DELETE FROM " + ddlTableNames.SelectedValue + " WHERE RecordId = #recordId"))
{
cmd.Connection = con;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
}
this.BindGrid(ddlTableNames.SelectedValue, Convert.ToInt32(hdnPageIndex.Value));
}
protected void btnGo_Click(object sender, EventArgs e)
{ int myInt;
if(txtPageSize.Text!=null && txtPageSize.Text !=string.Empty)
if(int.TryParse(txtPageSize.Text, out myInt)) pageSize = myInt;
hdnPageIndex.Value = "1";
this.BindGrid(ddlTableNames.SelectedValue, 1);
}
protected void AddNewButton_Click(object sender, EventArgs e)
{
hdnPageIndex.Value="1";
this.BindGrid(ddlTableNames.SelectedValue, Convert.ToInt32(hdnPageIndex.Value), true);
}
protected void OnRowDataBound_grdDynamic(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow && e.Row.RowIndex != grdDynamic.EditIndex)
{
(e.Row.Cells[0].Controls[2] as LinkButton).Attributes["onclick"] = "return confirm('Do you want to delete this row?');";
}
}
Hope it helps:
Hi i added template field dynamically to gridview by implementing ITemplate interface.
The template field contains some controls like label and textboxes. how do i get these controls in row databound event.
I am not able to get when i do gridviewrow.findcontrol("id") as i do normally when we add templatefield from aspx page.
The way i added template field is like this
public class CustomGridViewColumn : ITemplate
{
ListItemType _liType;
string _columnName;
public CustomGridViewColumn(ListItemType type, string column)
{
_liType = type;
_columnName = column;
}
void ITemplate.InstantiateIn(System.Web.UI.Control container)
{
switch (_liType)
{
case ListItemType.Header:
Label lblHeader = new Label();
lblHeader.Text = _columnName;
container.Controls.Add(lblHeader);
break;
case ListItemType.Item:
Label lblItem = new Label();
lblItem.DataBinding += new EventHandler(lbl_DataBinding);
lblItem.ID = "lbl" + _columnName;
lblItem.ClientIDMode = ClientIDMode.Predictable;
container.Controls.Add(lblItem);
DropDownList ddl = new DropDownList();
ddl.DataBinding += new EventHandler(ddl_DataBinding);
ddl.ID = "ddl" + _columnName;
ddl.Visible = false;
container.Controls.Add(ddl);
break;
}
}
}
Now i want access the label and dropdown which i have added using this code.
when i do gridviewrow.findcontrol("id") i am not getting them.
Can any one please help me.
I am geeting when i go through all the rows and try to find but
i have a check box in a row when i select it all labels should diappear and ddls dhould appear
for this i am using the follwoing code.
protected void chkEdit_CheckedChanged(object sender, EventArgs e)
{
CheckBox chkEditTest = (CheckBox)sender;
GridViewRow grow = (GridViewRow)chkEditTest.NamingContainer;
DropDownList ddl = (DropDownList)grow.FindControl("ddl");
Label lbl= (Label)grow.FindControl("lbl");
}
when i do this i am not able to get the controls.
it seems like controls are disapppearing on postback..
This is what I came up with and I can able to get the control reference in the code behind.
public class CustomGridViewColumn : ITemplate
{
ListItemType _liType; string _columnName;
public CustomGridViewColumn(ListItemType type, string column)
{
_liType = type;
_columnName = column;
}
void ITemplate.InstantiateIn(Control container)
{
switch (_liType)
{
case ListItemType.Header:
Label lblHeader = new Label();
lblHeader.Text = _columnName;
container.Controls.Add(lblHeader);
break;
case ListItemType.Item:
Label lblItem = new Label();
lblItem.DataBinding += new EventHandler(lblItem_DataBinding);
lblItem.ID = "lbl" + _columnName;
lblItem.ClientIDMode = ClientIDMode.Predictable;
container.Controls.Add(lblItem);
DropDownList ddl = new DropDownList();
ddl.DataBinding += new EventHandler(ddl_DataBinding);
ddl.ID = "ddl" + _columnName;
ddl.Visible = false;
ddl.DataSource = new string[] { "Hello", "World" };
container.Controls.Add(ddl);
break;
}
}
void ddl_DataBinding(object sender, EventArgs e)
{
}
void lblItem_DataBinding(object sender, EventArgs e)
{
}
}
protected void Page_Load(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt.Columns.Add("Name");
DataRow oItem = dt.NewRow();
oItem[0] = "Deepu";
dt.Rows.Add(oItem);
oItem = dt.NewRow();
oItem[0] = "MI";
dt.Rows.Add(oItem);
GridView gv = new GridView();
gv.ID = "myGridView";
gv.AutoGenerateColumns = false;
BoundField nameColumn = new BoundField();
nameColumn.DataField = "Name";
nameColumn.HeaderText = "Name";
gv.Columns.Add(nameColumn);
TemplateField TmpCol = new TemplateField();
TmpCol.HeaderText = "Template Column";
gv.Columns.Add(TmpCol);
TmpCol.ItemTemplate = new CustomGridViewColumn(ListItemType.Item, "TEST");
gv.DataSource = dt;
gv.DataBind();
Form.Controls.Add(gv);
}
protected void Button1_Click(object sender, EventArgs e)
{
GridView gv = Form.FindControl("myGridView") as GridView;
foreach (GridViewRow item in gv.Rows)
{
var ddl = item.FindControl("ddlTest") as DropDownList;
if (ddl != null)
{
ddl.Visible = true;
}
var lbl = item.FindControl("lbl") as Label;
if (lbl != null)
{
lbl.Text = "hello";
}
}
}
<form id="form1" runat="server">
<asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" />
</form>
Thanks
Deepu
Can you try using row index of GRIDVIEW control
var rowIndex = int.Parse(e.CommandArgument)
GridView1.Rows[rowIndex].FindControl("id")
Also refer
http://forums.asp.net/t/998368.aspx/1
http://www.codeproject.com/Articles/12021/Accessing-the-different-controls-inside-a-GridView
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridviewrow.aspx
Thanks
Deepu
when I click the > on my GridView it does not go to the next set of records.
DataGrid dataGrid = new DataGrid();
dataGrid.PageSize = 5;
dataGrid.AllowPaging = true;
dataGrid.EnableViewState = true;
dataGrid.DataSource = customerDataTable;
dataGrid.AllowPaging ();
if (!IsPostBack)
{
dataGrid.DataBind();
}
Depending on my code, it either stays on the first 5 or the grid does not show.
I've tried the DataBind() in and out of the IsPostBack.
I've also tried adding
dataGrid.PageIndexChanged += new DataGridPageChangedEventHandler(dataGrid_PageIndexChanged);
and
void dataGrid_PageIndexChanged(object source, DataGridPageChangedEventArgs e)
{
DataGrid dg = (DataGrid)source;
dg.DataBind();
}
But I can't get this to work. What am I doing wrong?
Thanks!
Here's an example I tried to recreate your scenario and it works. Check it out.
protected void Page_Load(object sender, EventArgs e)
{
GridView GridView1 = new GridView();
Panel1.Controls.Add(GridView1);
GridView1.DataSource = GetList();
GridView1.AutoGenerateColumns = true;
GridView1.EnableViewState = true;
GridView1.AllowPaging = true;
GridView1.PageSize = 4;
GridView1.DataBind();
GridView1.PageIndexChanging += new GridViewPageEventHandler(GridView1_PageIndexChanging);
}
void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
if (sender != null)
{
GridView GridView1 = sender as GridView;
GridView1.PageIndex = e.NewPageIndex;
GridView1.DataBind();
}
}
public class Person
{
public String Name { get; set; }
public int Age { get; set; }
}
private IEnumerable<Person> GetList()
{
List<Person> list = new List<Person>();
list.Add(new Person() {Age = 12, Name = "asdfsd"});
list.Add(new Person() {Age = 13, Name = "sdfsdaf"});
list.Add(new Person() {Age = 14, Name = "zxczxv"});
list.Add(new Person() { Age = 15, Name = "zxczxv" });
list.Add(new Person() { Age = 16, Name = "zxczxv" });
list.Add(new Person() { Age = 17, Name = "zxczxv" });
return list;
}
and in the markup all you need is to have the panel
<asp:Panel ID="Panel1" runat="server">
EDIT:
Here's the same scenario using DataGrid
protected void Page_Load(object sender, EventArgs e)
{
DataGrid dataGrid = new DataGrid();
Panel1.Controls.Add(dataGrid);
dataGrid.DataSource = GetList();
dataGrid.AutoGenerateColumns = true;
dataGrid.EnableViewState = true;
dataGrid.AllowPaging = true;
dataGrid.PageSize = 4;
dataGrid.DataBind();
dataGrid.PageIndexChanged +=new DataGridPageChangedEventHandler(dataGrid_PageIndexChanged);
}
void dataGrid_PageIndexChanged(object source, DataGridPageChangedEventArgs e)
{
if (source != null)
{
DataGrid dataGrid = source as DataGrid;
dataGrid.CurrentPageIndex = e.NewPageIndex;
dataGrid.DataBind();
}
}
I am able to create BoundFields and Footer-rows dynamically like this in my GridView:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
CreateGridView();
}
}
private void CreateGridView()
{
GridView1.Columns.Clear();
DataTable dataTable = Book.GetBooksDataSet().Tables[0];
CommandField cf = new CommandField();
cf.ShowEditButton = true;
GridView1.Columns.Add(cf);
int colCount = 1;
foreach (DataColumn c in dataTable.Columns)
{
BoundField boundField = new BoundField();
boundField.DataField = c.ColumnName;
boundField.HeaderText = c.ColumnName;
//boundField.FooterText = "---";
if (colCount == 3 || colCount == 5)
{
boundField.ReadOnly = true;
}
GridView1.Columns.Add(boundField);
colCount++;
}
GridView1.ShowFooter = true;
GridView1.DataSource = dataTable;
GridView1.DataBind();
GridViewRow footerRow = GridView1.FooterRow;
Button b = new Button();
b.Text = "Add New";
int i = 0;
footerRow.Cells[i].Controls.Add(b);
foreach (DataColumn c in dataTable.Columns)
{
++i;
TextBox tb = new TextBox();
footerRow.Cells[i].Controls.Add(tb);
}
}
....................................
....................................
....................................
}
But the problem is, when I click the "Add New" - button, it disappears instantly. And, also I am unable to add any event handler to it. Or intercept its actions like this:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
int index = Convert.ToInt32(e.CommandArgument);
if (e.CommandName == "Edit")
{
GridView1.EditIndex = index;
GridViewRow selectedRow = ((GridView)e.CommandSource).Rows[index];
//We can get cell data like this
string id = selectedRow.Cells[1].Text;
string isbn = selectedRow.Cells[2].Text;
//This is necessary to GridView to be showed up.
CreateGridView();
}
else if (e.CommandName == "Update")
{
LinkButton updateButton = (LinkButton)e.CommandSource;
DataControlFieldCell dcfc = (DataControlFieldCell)updateButton.Parent;
GridViewRow gvr = (GridViewRow)dcfc.Parent;
//The update...................
//Update grid-data to database
UpdateDataInTheDatabase(gvr.Cells[1].Controls);
//Grid goes back to normal
GridView1.EditIndex = -1;
//This is necessary to GridView to be showed up.
CreateGridView();
}
}
One more thing, I have seen some solutions that suggests to handle the GridView's rowBound event. But I need to do it from within Page_load event handler, or in, GridView1_RowCommand event handler.
Dynamically created controls mus be re-created on every postback. Your "Add New" button causes a postback so the dynamically created footer disappears. Is there a reason this grid has to be created dynamically? From the code you posted it appears that you could do this in markup instead. If not, you'll have to re-create the dynamic controls on every postback.
Edited to add:
I played with this a little bit and what's below works in that the grid doesn't disappear and events are handled, but it doesn't actually do anything. Hope this helps.
Markup:
<p><asp:Literal ID="Literal1" runat="server" /></p>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false"
OnRowCommand="GridView1_RowCommand"
OnRowEditing="GridView1_RowEditing"/>
Code:
protected void Page_Load(object sender, EventArgs e)
{
BindGridView();
}
private DataTable GetBooksDataTable()
{
var dt = new DataTable();
dt.Columns.Add("ID", typeof(int));
dt.Columns.Add("Title", typeof(string));
dt.Columns.Add("Author", typeof(string));
for (int index = 0; index < 10; index++)
{
dt.Rows.Add(index, "Title" + index, "Author" + index);
}
return dt;
}
private void BindGridView()
{
var dt = GetBooksDataTable();
GridView1.Columns.Clear();
GridView1.ShowFooter = true;
var cf = new CommandField();
cf.HeaderText = "Action";
cf.ShowEditButton = true;
GridView1.Columns.Add(cf);
for (int index = 0; index < dt.Columns.Count; index++)
{
var boundField = new BoundField();
boundField.DataField = dt.Columns[index].ColumnName;
boundField.HeaderText = dt.Columns[index].ColumnName;
GridView1.Columns.Add(boundField);
}
GridView1.DataSource = dt;
GridView1.DataBind();
var footer = GridView1.FooterRow;
var b = new LinkButton();
b.Text = "Add New";
b.CommandName = "Add New";
footer.Cells[0].Controls.Add(b);
for (int index = 1; index < dt.Columns.Count + 1; index++)
{
var tb = new TextBox();
footer.Cells[index].Controls.Add(tb);
}
}
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
Literal1.Text = e.CommandName;
}
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
Literal1.Text = "Editing row index " + e.NewEditIndex.ToString();
}
Move your code from Page_Load to Page_Init. Things added in the Page_Load last only for the lifecycle of one postback.
You'd then be able to add eventhandlers, intercept events etc.