how to bind a dropdownlist in gridview? - asp.net

I have a gridview in which every row contains a dropdownlist. I want to bind every dropdownlist dynamically. Can someone tell me how can i do it. Thanks in Advance

If you are using template column then you can bind your drop-down from mark-up using data-binding expressions. For example,
<asp:TemplateField HeaderText="XYZ">
<ItemTemplate>
<asp:DropDownList runat="server" ID="MyDD" DataSourceId="MyDataSource" />
</ItemTemplate>
</asp:TemplateField>
Above is assuming that your drop-down data in constant across rows. If it is changing then you can use data-binding expression such as
<asp:DropDownList runat="server" DataSource='<%# GetDropDownData(Container) %>' DataTextField="Text" DataValueField="Value" />
GetDropDownData will be a protected method in code-behind that will return the data (data-table, list, array) for the given row.
You can use GridView.RowDataBound event (or RowCreated event) in code-behind to fill drop-downs. For example,
protected void GridView_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
// Find the drop-down (say in 3rd column)
var dd = e.Row.Cells[2].Controls[0] as DropDownList;
if (null != dd) {
// bind it
}
/*
// In case of template fields, use FindControl
dd = e.Row.Cells[2].FindControl("MyDD") as DropDownList;
*/
}
}

In addition to the proposed methods, you may also bind your controls within your markup, in this way:
<asp:GridView ID="MyGrid" runat="server" DataSourceID="MyDataSource1">
<Columns>
<asp:TemplateField>
<EditItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server" SelectedValue='<%# Bind ("CustomerId") %>' DataSourceID="CustomersDataSource" DataTextField="CustomerName" DataValueField="CustomerId" >
</asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>

Here is your gridview
<asp:GridView ID="grvExcelData" runat="server" onrowdatabound="GridView2_RowDataBound">
<HeaderStyle BackColor="#df5015" Font-Bold="true" ForeColor="White" />
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:DropDownList ID="DrdDatabase" Width="100px" runat="server">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
and your RowDataBound event for the gridview would be
protected void GridView2_RowDataBound(object sender, GridViewRowEventArgs e)
{
string cities = "maxico,chennai,newdelhi,hongkong";
string [] arr = cities.Split(',');
// Instead of string array it could be your data retrieved from database.
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList ddl = (DropDownList)e.Row.FindControl("DrdDatabase");
foreach (string colName in arr )
ddl.Items.Add(new ListItem(colName));
}
}

protected void gvSalesAppData_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList ddlCurrentPhase = (DropDownList)e.Row.FindControl("ddlCurrentPhase");
DropDownList ddlProductFamily = (DropDownList)e.Row.FindControl("ddlProductFamily");
DropDownList ddlProductGroup = (DropDownList)e.Row.FindControl("ddlProductGroup");
DropDownList ddlETProgramManager = (DropDownList)e.Row.FindControl("ddlETProgramManager");
DropDownList ddlPLMForTheProduct = (DropDownList)e.Row.FindControl("ddlPLMForTheProduct");
TrackingToolObj.BindCurrentPhases(ddlCurrentPhase);
TrackingToolObj.BindCurrentPhases(ddlProductFamily);
TrackingToolObj.BindProductGroups(ddlProductGroup);
TrackingToolObj.GetEmployeesBasedOnRoleTypeId(ddlETProgramManager, (int)OSAEnums.RoleTypes.ProgramManager, false);
TrackingToolObj.GetEmployeesBasedOnRoleTypeId(ddlPLMForTheProduct, (int)OSAEnums.RoleTypes.PLM, false);
}
}

Binding the GridView
Below is the code to Bind the GridView control with data.
C#
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
this.BindData();
}
}
private void BindData()
{
string query = "SELECT top 10 * FROM Customers";
SqlCommand cmd = new SqlCommand(query);
gvCustomers.DataSource = GetData(cmd);
gvCustomers.DataBind();
}
private DataTable GetData(SqlCommand cmd)
{
string strConnString = ConfigurationManager.ConnectionStrings["conString"].ConnectionString;
using (SqlConnection con = new SqlConnection(strConnString))
{
using (SqlDataAdapter sda = new SqlDataAdapter())
{
cmd.Connection = con;
sda.SelectCommand = cmd;
using (DataTable dt = new DataTable())
{
sda.Fill(dt);
return dt;
}
}
}
}

Related

I can't paint the rows of another page in the gridview, asp.net

I can't solve one thing, I want to paint some rows of the GridView depending on a column. I have no problems with this, but when I change the page, I can't get it to paint.
This is how I do the pagination
GridView2.PageIndex = e.NewPageIndex;
loadgrid();
paintpagin(e.NewPageIndex);
So I try to paint it
GridView2.PageIndex = newPageIndex;
foreach (GridViewRow Rowe in GridView2.Rows)
{
CheckBox Rc = (CheckBox)Rowe.FindControl("rdaprobar");
RadioButton Ri = (RadioButton)Rowe.FindControl("rdpendiente");
RadioButton Rd = (RadioButton)Rowe.FindControl("rdCandelar");
if (Rc.Checked == true)
{
GridView2.Rows[Rowe.DataItemIndex].BackColor = ColorTranslator.FromHtml("#bcf5be");
}
}
The even to use for highlights, formatting, etc.?
use the Grid row data bound event.
So, first up, our markup:
<asp:GridView ID="GHotels" runat="server" CssClass="table" AutoGenerateColumns="false"
width="45%" DataKeyNames="ID" OnRowDataBound="GHotels_RowDataBound" AllowPaging="True"
OnPageIndexChanging="GHotels_PageIndexChanging" >
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:TemplateField HeaderText="HotelName">
<ItemTemplate>
<asp:Label ID="txtHotel" runat="server" Text='<%# Eval("HotelName") %>' ></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Description" HeaderText="Description" ItemStyle-Width="270" />
</Columns>
<PagerStyle CssClass="GridPager" />
</asp:GridView>
Code to load:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadData();
}
void LoadData()
{
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
string strSQL =
"SELECT * FROM tblHotels WHERE Description is not null ORDER BY HotelName";
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
DataTable rstData = new DataTable();
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
GHotels.DataSource = rstData;
GHotels.DataBind();
}
}
}
Our pager code (and NOTE YOU HAVE the load of the grid before the pager - chec your code!!!).
protected void GHotels_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GHotels.PageIndex = e.NewPageIndex;
LoadData();
}
Ok, we now have this:
Now, I highlight each hotel if it is active. NOTE very careful, I don't have that column "active" in the GV, but it was/is part of the data source. So, for bonus points, I demonstrate how to get/grab/use columns that you don't render or have in the GV, but in fact is part of the data source.
So, our code to highlight, we have this:
protected void GHotels_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// get binding data source
DataRowView gData = e.Row.DataItem as DataRowView;
if ((bool)gData["Active"]) {
// Label tHotel = e.Row.FindControl("txtHotel") as Label;
// tHotel.BackColor = System.Drawing.Color.LightSteelBlue;
e.Row.Cells[2].BackColor = System.Drawing.Color.LightSteelBlue;
}
}
}
So, we now have this:
So do NOT try and loop each row of the GV - use the row data bound to highlight and format as per above.

Data Going Out of Synch when using GridView inside UpdatePanel

Data in my GridView inside an UpdatePanel is going out of synch with the database and I can't figure out why. This has resulted in incorrect updates to the database which I have to fix rapidly! Can anyone help?
I have multiple UpdatePanels that have GridViews inside that can be edited by the user. There is a search feature and filter buttons that select queried data from the database and display in the GridView. There is sorting enabled and the "out of synchness" occurs mostly when sorting and then editing a field.
The data comes from a SQL Database. I can update the data directly through OnTextChange option of my TemplateField like this:
<asp:GridView
ID="GridView4"
runat="server"
OnSorting="TaskGridView_Sorting"
AllowSorting="True"
Width="100%" >
<Columns>
<asp:TemplateField SortExpression="name" HeaderText="Name">
<HeaderStyle HorizontalAlign="Left" CssClass="col_name" />
<ItemTemplate>
<asp:TextBox ID="name" AutoPostBack="True" CssClass="col_name" runat="server" Text='<%# Eval("name") %>' Width=180 OnTextChanged="text_change" />
</ItemTemplate>
</asp:TemplateField>
...
I have my gridview inside an UpdatePanel that has these options:
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
...
I have enabled partial rendering like this:
<ajaxToolKit:ToolkitScriptManager EnablePartialRendering="true" runat="server" />
I have buttons that filter the data by requerying the database and displaying just the filtered data like this:
DataGrid_Load(DAL.Search_reg_log(OrgText.Text, searchText, searchCol), "reg");
The gridview gets its data loaded like this:
private void DataGrid_Load(DataTable command, string type)
{
DataTable dataTable = new DataTable();
dataTable = command;
string sortDir = ViewState["SortDirection"] as string;
string sortExp = ViewState["SortExpression"] as string;
if(ViewState["SortExpression"] != null)
{
dataTable = resort(dataTable, sortExp, sortDir);
}
try
{
var query = from c in dataTable.AsEnumerable()
where c.Field<string>("status") == "Invoiced" && c.Field<string>("reg_cat_id") != "Archive"
|| c.Field<string>("status") == "Confirmed" && c.Field<string>("reg_cat_id") != "Archive"
select c ;
if(query.Any()){
DataTable t2 = query.CopyToDataTable();
GridView4.DataSource = t2;
GridView4.DataBind();
} else {
GridView4.DataSource = new DataTable();
GridView4.DataBind();
}
}
catch(Exception e) {
ErrorText.Text = "Caught Exception: " + e;
}
...
I have isolated one cause of the data errors which occurs after sorting a column and then
protected void TaskGridView_Sorting(object sender, GridViewSortEventArgs e)
{
string sortExp = ViewState["SortExpression"] as string;
string sortDir = ViewState["SortDirection"] as string;
if(sortDir == "asc" & sortExp == e.SortExpression.ToString())
ViewState["SortDirection"] = "desc";
else
ViewState["SortDirection"] = "asc";
ViewState["SortExpression"] = e.SortExpression.ToString();
if(searchCol != "" && searchText != "")
DataGrid_Load(DAL.Search_reg_log(OrgText.Text, searchText, searchCol), "reg");
else
DataGrid_Load(DAL.reg_log(HeadText.Text, OrgText.Text), "reg");
UpdatePanels();
}
Here is the resort function:
public static DataTable resort(DataTable dt, string colName, string direction)
{
dt.DefaultView.Sort = colName + " " + direction;
dt = dt.DefaultView.ToTable();
return dt;
}
Please help with some direction of what might be causing this.
It looks like you are having some trouble with GridView and updating them. I will post a complete working example below. Start with that and gradually update that code to fit your own needs, like getting data with var query = from c in dataTable.AsEnumerable(). The important thing is to sort the data every time you (re)bind the GridView data. And I'm not sure what is happening inside resort, but you have to use dt.DefaultView.ToTable(); to save the sorting in the DataTable.
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:GridView ID="GridView1" runat="server"
DataKeyNames="ID" AllowSorting="true"
OnSorting="GridView1_Sorting"
AutoGenerateColumns="false"
AutoGenerateEditButton="true"
OnRowEditing="GridView1_RowEditing"
OnRowCancelingEdit="GridView1_RowCancelingEdit"
OnRowUpdating="GridView1_RowUpdating">
<Columns>
<asp:TemplateField HeaderText="ID" SortExpression="ID">
<ItemTemplate>
<%# Eval("ID") %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Name" SortExpression="name">
<ItemTemplate>
<%# Eval("name") %>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text=' <%# Eval("name") %>'></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Literal ID="Literal1" runat="server"></asp:Literal>
</ContentTemplate>
</asp:UpdatePanel>
Code behind
protected void Page_Load(object sender, EventArgs e)
{
//bind data in an ispostback check
if (!IsPostBack)
{
DataGrid_Load();
}
}
private void DataGrid_Load()
{
//load the datatable data
DataTable dt = source;
//check if the viewsstate existst
if (ViewState["SortExpression"] != null && ViewState["SortDirection"] != null)
{
//sort the datatable before binding it to the gridview
dt.DefaultView.Sort = ViewState["SortExpression"] + " " + ViewState["SortDirection"];
dt.DefaultView.ToTable();
}
//bind the sorted datatable to the gridvidw
GridView1.DataSource = dt;
GridView1.DataBind();
}
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
//load the previous sorting settigns
string sortExp = ViewState["SortExpression"] as string;
string sortDir = ViewState["SortDirection"] as string;
//reverse the direction if the column is the same as the previous sort
if (sortDir == "asc" & sortExp == e.SortExpression.ToString())
ViewState["SortDirection"] = "desc";
else
ViewState["SortDirection"] = "asc";
//put the current sort column in the viewstate
ViewState["SortExpression"] = e.SortExpression.ToString();
//rebind data
DataGrid_Load();
}
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
//set the edit index and rebind data
GridView1.EditIndex = e.NewEditIndex;
DataGrid_Load();
}
protected void GridView1_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
//reset the edit index and rebind data
GridView1.EditIndex = -1;
DataGrid_Load();
}
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
//use findcontrol to locate the textbox in the edit template
TextBox tb = (TextBox)GridView1.Rows[e.RowIndex].FindControl("TextBox1");
//get the id of the row from the datakeys
int id = Convert.ToInt32(GridView1.DataKeys[e.RowIndex].Values[0]);
//show result for testing
Literal1.Text = "ID: " + id + "<br>Name: " + tb.Text;
//reset the edit index and rebind data
GridView1_RowCancelingEdit(null, null);
}

method of populate dropdownlist inside gridview

If i want to populate a DropdownList in a GridView what will be the best way? use GridView 'OnRowDataBound' event and fetch query everytime to db or get all data first and put it on datatable and do further work from this datatable ?
As your question is unclear about your requirement, I assume that you want to bind dropdownlist inside the Gridview using OnRowDataBound event of gridview.
So here are the steps:-
Add a Gridview HTML in your aspx page with DropDownList in ItemTemplate of TemplateField.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" OnRowDataBound="OnRowDataBound">
<Columns>
<asp:BoundField HeaderText="Name" DataField="ContactName" />
<asp:TemplateField HeaderText = "Country">
<ItemTemplate>
<asp:Label ID="lblCountry" runat="server" Text='<%# Eval("Country") %>' Visible = "false" />
<asp:DropDownList ID="ddlCountries" runat="server">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Then you need to bind the gridview with records which will come from the database.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GridView1.DataSource = GetData("SELECT ContactName, Country FROM Customers");
GridView1.DataBind();
}
}
private DataSet GetData(string query)
{
string conString = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
SqlCommand cmd = new SqlCommand(query);
using (SqlConnection con = new SqlConnection(conString))
{
using (SqlDataAdapter sda = new SqlDataAdapter())
{
cmd.Connection = con;
sda.SelectCommand = cmd;
using (DataSet ds = new DataSet())
{
sda.Fill(ds);
return ds;
}
}
}
}
Then the code for OnRowDataBound will follow like below :-
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//Find the DropDownList in the Row
DropDownList ddlCountries = (e.Row.FindControl("ddlCountries") as DropDownList);
ddlCountries.DataSource = GetData("SELECT DISTINCT Country FROM Customers");
ddlCountries.DataTextField = "Country";
ddlCountries.DataValueField = "Country";
ddlCountries.DataBind();
//Add Default Item in the DropDownList
ddlCountries.Items.Insert(0, new ListItem("Please select"));
//Select the Country of Customer in DropDownList
string country = (e.Row.FindControl("lblCountry") as Label).Text;
ddlCountries.Items.FindByValue(country).Selected = true;
}
}
See the Reference link for your reference
Also see the Working demo for your reference
Hope that helps.

Get value from ASP.NET GridView with TextBox on server

I have a gridview with textbox inside
I want to get value of this textbox on button click
But I always receiving "0" (default) value
I think this problem related to viewstate but I'm not sure
Tell me please what I'm doing wrong?
Source code:
protected void Page_Load(object sender, EventArgs e)
{
DataSet dataSet = new DataSet("MyDataSet");
DataTable table = new DataTable();
table.Columns.Add(new DataColumn("NameValue"));
table.Columns.Add(new DataColumn("Number"));
table.Columns.Add(new DataColumn("NumberValue"));
dataSet.Tables.Add(table);
DataRow row = dataSet.Tables[0].NewRow();
row[0] = "Name";
row[1] = "0";
dataSet.Tables[0].Rows.Add(row);
this.MyGridView.DataSource = dataSet;
this.MyGridView.DataBind();
}
protected void Button1_Click(object sender, EventArgs e)
{
TextBox txtsn = ((TextBox)this.MyGridView.Rows[0].FindControl("NumberTextBox"));
string sn = txtsn.Text;
}
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
<asp:GridView ID="MyGridView" AutoGenerateColumns="false" ShowHeader="false" runat="server" >
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="NameLabel" runat="server" Text='<%#Eval("NameValue")%>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="NumberTextBox" runat="server" Text='<%#Eval("NumberValue")%>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</form>
</body>
The problem is that you always bind the grid to it's DataSource even on postbacks. That overrides all changes made by the user.
Instead use the IsPostBack property:
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostback)
{
DataSet dataSet = new DataSet("MyDataSet");
DataTable table = new DataTable();
table.Columns.Add(new DataColumn("NameValue"));
table.Columns.Add(new DataColumn("Number"));
table.Columns.Add(new DataColumn("NumberValue"));
dataSet.Tables.Add(table);
DataRow row = dataSet.Tables[0].NewRow();
row[0] = "Name";
row[1] = "0";
dataSet.Tables[0].Rows.Add(row);
this.MyGridView.DataSource = dataSet;
this.MyGridView.DataBind();
}
}
You need to reload the DataSource only if something was changed(f.e. a record was deleted or added, the user clicked a sort-column or you have paging). But then you should do that only in the appropriate event handlers and not in page_load. So it's best to wrap this code in a method which you can call from anywhere.
You're data binding your grid on postbacks, which is causing this issue. You want to check to see if the request is a post:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostback)
{
DataSet dataSet = new DataSet("MyDataSet");
DataTable table = new DataTable();
table.Columns.Add(new DataColumn("NameValue"));
table.Columns.Add(new DataColumn("Number"));
table.Columns.Add(new DataColumn("NumberValue"));
dataSet.Tables.Add(table);
DataRow row = dataSet.Tables[0].NewRow();
row[0] = "Name";
row[1] = "0";
dataSet.Tables[0].Rows.Add(row);
this.MyGridView.DataSource = dataSet;
this.MyGridView.DataBind();
}
}

ASP.NET - Problem with GridView with Dynamic Columns

I have a GridView that includes BoundField and TemplateField elements. Some of the TemplateField elements are dynamically generated. For the sake of reference, here is the GridView that I am using
<asp:GridView ID="myGridView" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" ShowFooter="True" EnableModelValidation="True"
OnLoad="myGridView_Load" OnRowCommand="myGridView_RowCommand"
OnRowEditing="myGridView_RowEditing" OnRowDeleting="myGridView_RowDeleting"
OnRowCancelingEdit="myGridView_RowCancelingEdit"
OnRowUpdating="myGridView_RowUpdating">
<Columns>
<asp:BoundField DataField="Number" Visible="true" HeaderText="Test" />
<asp:TemplateField HeaderText="Number">
<EditItemTemplate>
<asp:TextBox ID="tb1" runat="server" Text='<%# Bind("Number") %>' />
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lb1" runat="server" Text='<%# Bind("Number") %>' />
</ItemTemplate>
<FooterTemplate>
<asp:TextBox ID="ftb" runat="server" Text="[x]" />
</FooterTemplate>
</asp:TemplateField>
<%-- Dynamically Generated Columns Will Be Inserted Here --%>
<asp:TemplateField HeaderText="Actions">
<EditItemTemplate>
<asp:LinkButton ID="ulb" runat="server" Text="update" CommandName="Update" />
<asp:LinkButton ID="clb" runat="server" Text="cancel" CommandName="Cancel" />
</EditItemTemplate>
<FooterTemplate>
<asp:LinkButton ID="slb" runat="server" Text="insert"
OnClick="saveLinkButton_Click" />
</FooterTemplate>
<ItemTemplate>
<asp:LinkButton ID="elb" runat="server" Text="edit" CommandName="Edit" />
<asp:LinkButton ID="dlb" runat="server" Text="delete" CommandName="Delete" />
</ItemTemplate>
</asp:TemplateField
</Columns>
<EmptyDataTemplate>
<table border="0" cellpadding="0" cellspacing="0">
<tr><td>Number</td></tr>
<tr>
<td><asp:TextBox ID="ntb" runat="server" /></td>
<td><asp:LinkButton ID="slb2" runat="server" Text="save" OnClick="saveLinkButton_Click" /></td>
</tr>
</table>
</EmptyDataTemplate>
</asp:GridView>
When the GridView initially loads, everything is loaded properly. However, anytime I perform a command (edit, insert, delete), all of the data goes away. Oddly, the BoundField values still appear correctly. However, any TemplateField does not seem to get rendered. The code that I am using to work with this GridView is here:
public partial class GridView : System.Web.UI.Page
{
private List<string> dynamicColumnNames = new List<string>();
protected void Page_Load(object sender, EventArgs e)
{
LoadPageData();
}
protected void saveLinkButton_Click(object sender, EventArgs e)
{
}
protected void myGridView_Load(object sender, EventArgs e)
{
if (Page.IsPostBack == false)
{
BindGridData();
}
}
protected void myGridView_RowCommand(object sender, GridViewCommandEventArgs e)
{ }
protected void myGridView_RowEditing(object sender, GridViewEditEventArgs e)
{
myGridView.EditIndex = e.NewEditIndex;
BindGridData();
}
protected void myGridView_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
LoadPageData();
BindGridData();
}
protected void myGridView_RowCancelingEdit(object sender, EventArgs e)
{
myGridView.EditIndex = -1;
BindGridData();
}
protected void myGridView_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
myGridView.EditIndex = -1;
LoadPageData();
BindGridData();
}
private void BindGridData()
{
// Create a temporary data source
DataTable tempData = new DataTable();
tempData.Columns.Add("ID");
tempData.Columns.Add("Number");
// Dynamically add template columns
foreach (string columnName in dynamicColumnNames)
{
tempData.Columns.Add(columnName);
TemplateField templateField = new TemplateField();
templateField.HeaderTemplate = new MyTemplateField(ListItemType.Header, columnName);
templateField.ItemTemplate = new MyTemplateField(ListItemType.Item, columnName);
templateField.EditItemTemplate = new MyTemplateField(ListItemType.EditItem, columnName);
templateField.FooterTemplate = new MyTemplateField(ListItemType.Footer, columnName);
myGridView.Columns.Insert(2, templateField);
}
// Add some phony data
Random random = new Random(DateTime.Now.Millisecond);
for (int i = 0; i < 10; i++)
{
DataRow tempRow = tempData.NewRow();
tempRow["Number"] = (i + 1);
foreach (string column in dynamicColumnNames)
tempRow[column] = random.NextDouble();
tempData.Rows.Add(tempRow);
}
// Bind the data to the grid
myGridView.DataSource = tempData;
myGridView.DataBind();
}
private void LoadPageData()
{
dynamicColumnNames.Add("USA");
dynamicColumnNames.Add("Japan");
dynamicColumnNames.Add("Mexico");
}
}
internal class MyTemplateField : ITemplate
{
// The type of the list item
private ListItemType listItemType;
// The value to use during instantiation
private string value1 = string.Empty;
public MyTemplateField(ListItemType listItemType, string value1)
{
this.listItemType = listItemType;
this.value1 = value1;
}
public void InstantiateIn(Control container)
{
if (listItemType == ListItemType.Item)
{
TextBox textBox = new TextBox();
textBox.ReadOnly = true;
textBox.DataBinding += new EventHandler(textBox_DataBinding);
container.Controls.Add(textBox);
}
else if (listItemType == ListItemType.EditItem)
{
TextBox textBox = new TextBox();
textBox.DataBinding += new EventHandler(textBox_DataBinding);
container.Controls.Add(textBox);
}
else if (listItemType == ListItemType.Header)
{
Literal literal = new Literal();
literal.Text = value1;
container.Controls.Add(literal);
}
else if (listItemType == ListItemType.Footer)
{
TextBox textBox = new TextBox();
container.Controls.Add(textBox);
}
}
private void textBox_DataBinding(object sender, EventArgs e)
{
TextBox textBox = (TextBox)(sender);
GridViewRow row = (GridViewRow)(textBox.NamingContainer);
textBox.Text = DataBinder.Eval(row.DataItem, value1).ToString();
}
}
How do I use commands in a GridView with Dynamically added columns? What is wrong with my code?
Thank you!
Dynamically added controls must be added on each post, you can't just add these controls on the first page load. Try removing your BindGridData() from within the Page.IsPostBack == false.

Resources