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:
Related
this code display total of column in each page of grid view footer I want to display total of all columns in all pages footer
if (e.Row.RowType == DataControlRowType.DataRow)
{
string deb = ((Label)e.Row.FindControl("debit")).Text;
string cred = ((Label)e.Row.FindControl("credit")).Text;
decimal totalvalue = Convert.ToDecimal(deb) - Convert.ToDecimal(cred);
amount += totalvalue;
Label lbl = (Label)e.Row.FindControl("lblTotal");
lbl.Text = amount.ToString();
Label lblDebAmount = (Label)e.Row.FindControl("debit");
Label lblCredamount = (Label)e.Row.FindControl("credit");
float debtotal = (float)Decimal.Parse(lblDebAmount.Text);
float credtotal = (float)Decimal.Parse(lblCredamount.Text);
totalPriced += debtotal;
totalPricec += credtotal;
}
if (e.Row.RowType == DataControlRowType.Footer)
{
Label totallblCAmount = (Label)e.Row.FindControl("totallblDebAmount");
Label totallblCredAmount = (Label)e.Row.FindControl("totallblCredAmount");
totallblCAmount.Text = totalPriced.ToString("###,###.000");
totallblCredAmount.Text = totalPricec.ToString("###,###.000");
}
}
Why do it when the row is data bound? Why not do it when you originally bind the data?
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
DataTable dt = Database.GetData();
GridView1.DataSource = dt;
GridView1.DataBind();
//calculate here by manually adding up the debit/credit column from dt
//or do a separate database call that calculates the sum, ex: select sum(debits), sum(credits) from general_ledger
}
}
It makes sense to let the database do the math calculation for you. You wouldn't need to write your own custom calculation code. Just let the database's sum function handle it.
Here's a little more detail.
//Executes a SqlCommand and returns a DataTable
public class GetDataTable(SqlCommand command)
{
var dt = new DataTable();
using (var connection = new SqlConnection("connectionstring"))
{
command.Connection = connection;
connection.Open();
dt.Load(command.ExecuteReader());
}
return dt;
}
//Executes a SqlCommand and returns a scalar of type T
public static T GetScalar<T>(SqlCommand command)
{
using (var connection = new SqlConnection ("connectionstring"))
{
command.Connection = connection;
connection.Open();
var result = command.ExecuteScalar();
if (result is T)
{
return (T)result;
}
else
{
return (T)Convert.ChangeType(result, typeof(T));
}
}
}
//Load the data into the GridView, then get the credit amount and put the value in a label.
//You'll need to adjust the queries to match your schema
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
var tableCommand = new SqlCommand("select columns from table");
GridView1.DataSource = GetDataTable(tableCommand);
GridView1.DataBind();
var creditCommand = new SqlCommand("select sum(stat_amount) from tablename where stat_flag='c'");
var credits = GetScalar<decimal>(creditCommand);
Label1.Text = credits;
}
}
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
I want to show Employee details in GridView. My client wants that he should be able to update the record without clicking on Edit button to update. Hence I kept everything in the ItemTemplate field of the GridView.
My Database tables are:
Emp(EmpNo, EName, Sal, DeptNo)
Dept(DeptNo, DeptName, Location)
Hence, I have written one sp to get data: EmpNo, EName, Sal, DeptName
Here, I want to show DeptName field in DropDownList. Here only I am facing the problem. DropDownList is not filling with proper DeptName value, but the first field.
My code-behind is like below:
public partial class GvwEmployee : System.Web.UI.Page
{
SqlConnection objConn = new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings["STERIAConnectionString"].ConnectionString);
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
GridView1.DataSource = EmployeeList;
GridView1.DataBind();
}
}
private List<Employee> EmployeeList
{
get{
List<Employee> employeeList = new List<Employee>();
SqlCommand objCmd = new SqlCommand("usp_GetEmpDetails", objConn);
objCmd.CommandType = CommandType.StoredProcedure;
objConn.Open();
SqlDataReader objDR = objCmd.ExecuteReader();
while (objDR.Read())
{
Employee employee = new Employee();
employee.EmpNo = Convert.ToInt32(objDR["EmpNo"]);
employee.EName = Convert.ToString(objDR["EName"]);
employee.Salary = Convert.ToDouble(objDR["Salary"]);
employee.DeptNo = Convert.ToInt32(objDR["DeptNo"]);
employee.DeptName = Convert.ToString(objDR["DeptName"]);
employeeList.Add(employee);
}
objDR.Close();
objConn.Close();
return employeeList;
}
}
private List<Department> DeptList
{
get
{
List<Department> deptList = new List<Department>();
SqlCommand objCmd = new SqlCommand("usp_GetDeptDetails", objConn);
objCmd.CommandType = CommandType.StoredProcedure;
objConn.Open();
SqlDataReader objDR = objCmd.ExecuteReader();
while (objDR.Read())
{
Department dept = new Department();
dept.DeptNo = Convert.ToInt32(objDR["DEPTNO"]);
dept.DName = Convert.ToString(objDR["DNAME"]);
dept.Location = Convert.ToString(objDR["Location"]);
deptList.Add(dept);
}
objDR.Close();
objConn.Close();
return deptList;
}
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList ddlDeptName = e.Row.FindControl("ddlDeptName") as DropDownList;
if (ddlDeptName != null)
{
ddlDeptName.DataSource = DeptList;
ddlDeptName.DataBind();
ddlDeptName.SelectedValue = GridView1.DataKeys[e.Row.RowIndex].Value.ToString();
}
}
if (e.Row.RowType == DataControlRowType.Footer)
{
}
}
}
Can anyone please tell where is the problem, why DeptName DropDownList is not filling with its proper values?
Try this way
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var index = Convert.ToInt32(e.RowIndex.ToString());
GridViewRow row = GridView1.Rows[index];
var ddlDeptName = row.FindControl("ddlDeptName") as ddlDeptName;
if (ddlDeptName != null)
{
ddlDeptName.DataSource = DeptList;
ddlDeptName.DataTextField = "DName";
ddlDeptName.DataValueField = "DeptNo";
ddlDeptName.DataBind();
var item = new ListItem("Select Department", "");
ddlDeptName.Items.Insert(0, item);
}
}
}
I got the solution like below:
In the GridView1_RowDataBound event method, I have written the following line of code to map DropDownList with the Data got from Backend.
//ddlDeptName.SelectedValue = GridView1.DataKeys[e.Row.RowIndex].Value.ToString();
Now, I have replaced the above line with the following line of code, and hence the problem was solved:
ddlDeptName.SelectedValue = ((Employee)e.Row.DataItem).DeptNo.ToString();
and this has solved my problem.
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();
}
when i am trying to display result in gridview using LINQ i am getting this error message."Both DataSource and DataSourceID are defined on 'GridView1'. Remove one definition." i am not getting any clue what to do? Here is my code
protected void SelectBtn_Click(object sender, EventArgs e)
{
ShowEmployee();
}
private void ShowEmployee()
{
DataClassesDataContext db = new DataClassesDataContext();
var name = from E in db.Employees
orderby E.Age ascending
select E;
GridView1.DataSource = name;
GridView1.DataBind();
}
protected void InsertBtn_Click(object sender, EventArgs e)
{
int id = Convert.ToInt32(TxtId.Text);
string name = TxtName.Text;
string address = TxtAddress.Text;
int age = Convert.ToInt32(TxtAge.Text);
DataClassesDataContext db = new DataClassesDataContext();
try
{
Employee emp = new Employee { EmployeeId = id, Name = name, Address = address, Age = age };
db.Employees.InsertOnSubmit(emp);
db.SubmitChanges();
LblMessage.Text = "Employee has been added successfully";
TxtId.Text = "";
TxtName.Text = "";
TxtAddress.Text = "";
TxtAge.Text = "";
ShowEmployee();
}
catch (Exception ee)
{
LblMessage.Text = ee.Message.ToString();
}
}
protected void UpdateBtn_Click(object sender, EventArgs e)
{
string name=TxtName.Text;
string address=TxtAddress.Text;
DataClassesDataContext db = new DataClassesDataContext();
Employee emp = db.Employees.FirstOrDefault(E => E.Name.StartsWith(name));
emp.Address = address;
db.SubmitChanges();
ShowEmployee();
}
protected void DeleteBtn_Click(object sender, EventArgs e)
{
DataClassesDataContext db = new DataClassesDataContext();
Employee emp = db.Employees.Single(E => E.Address.StartsWith("Delhi"));
db.Employees.DeleteOnSubmit(emp);
db.SubmitChanges();
ShowEmployee();
}
You set the DataSourceID property in the markup of GridView1 to "LinqDataSource1". That binds the grid to the LinqDataSource declared just after the GridView. Then in ShowEmployee() you set the DataSource property in code, which binds the grid to the query in that method. You can't do both. Remove the DataSourceID in markup if you intend to bind in code.
Clear DataSourceID property in design-time of your grid if you want to initialize dataset using C# code. I prefer this approach. In other case don't initialize dataset in run-time.