I am Using Membership to define roles in Asp.net.Now as per my requirement i need to show the Roles as dynamic Columns of gridview with first two columns as fixed and rest of the columns as per the number of Roles in table but i have no idea of how to meet that as i have never worked on it before..
Here is my static gridview code in aspx page...
<asp:GridView ID="GridView1" runat="server" OnRowDataBound="GridView1_RowDataBound"
AutoGenerateColumns="False" BackColor="LightGoldenrodYellow" BorderColor="Tan"
BorderWidth="1px" CellPadding="2" ForeColor="Black" GridLines="None"
Width="477px">
<AlternatingRowStyle BackColor="PaleGoldenrod" />
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<asp:CheckBox ID="chkhdr" runat="server" />
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="chkChild" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Username">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("col0") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Role(Admin)">
<ItemTemplate>
<asp:CheckBox ID="chkAdmin" runat="server" Checked='<%# Eval("col1") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Role(DPAO User )">
<ItemTemplate>
<asp:CheckBox ID="chkUser" runat="server" Checked='<%# Eval("col2") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Role(GeneralUser)">
<ItemTemplate>
<asp:CheckBox ID="chkgen" runat="server" Checked='<%# Eval("col3") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And here is the code to load grid with data...
protected void BindGridviewData()
{
var role = from MembershipUser u in Membership.GetAllUsers()
select new
{
User = u.UserName,
Role = string.Join(",", Roles.GetRolesForUser(u.UserName))
};
DataTable dTable = new DataTable();
dTable.Columns.Add("col0", typeof(string));
dTable.Columns.Add("col1", typeof(bool));
dTable.Columns.Add("col2", typeof(bool));
dTable.Columns.Add("col3", typeof(bool));
foreach (MembershipUser u in Membership.GetAllUsers())
{
DataRow dRow = dTable.NewRow();
dRow[0] = u.UserName;
string[] roles = Roles.GetRolesForUser(u.UserName);
dRow[1] = roles.Contains("Admin") ? true : false;
dRow[2] = roles.Contains("DPAO User") ? true : false;
dRow[3] = roles.Contains("GeneralUser") ? true : false;
dTable.Rows.Add(dRow);
}
GridView1.DataSource = dTable;
GridView1.DataBind();
}
In the given Grid I need first two columns as fixed and other column based on value from the Role table from membership...
Any help will be highly appreciated.Thanks in advance..
For dynamically Show , Update roles and Delete records try this:
ASPX:
<asp:GridView ID="GridView1" runat="server" onrowdatabound="GridView1_RowDataBound1"/></asp:GridView>
<asp:Button ID="cmdDelete" runat="server" onclick="cmdDelete_Click1" Text="Delete" />
<asp:Button ID="cmdUpdateRole" runat="server" onclick="cmdUpdateRole_Click" Text="Update Roles" />
Code behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindGridviewData();
}
}
protected void BindGridviewData()
{
DataTable dTable = new DataTable();
dTable.Columns.Add("Select", typeof(bool));
dTable.Columns.Add("Username", typeof(string));
dTable.Columns.Add("Role(Admin)", typeof(bool));
dTable.Columns.Add("Role(DPAO User)", typeof(bool));
dTable.Columns.Add("Role(GeneralUser)", typeof(bool));
foreach (MembershipUser u in Membership.GetAllUsers())
{
DataRow dRow = dTable.NewRow();
dRow[0] = false;
dRow[1] = u.UserName;
string[] roles = Roles.GetRolesForUser(u.UserName);
dRow[2] = roles.Contains("Admin") ? true : false;
dRow[3] = roles.Contains("DPAO User") ? true : false;
dRow[4] = roles.Contains("GeneralUser") ? true : false;
dTable.Rows.Add(dRow);
}
GridView1.DataSource = dTable;
GridView1.DataBind();
}
protected void cmdUpdateRole_Click(object sender, EventArgs e)
{
foreach (GridViewRow row in GridView1.Rows)
{
string username = row.Cells[1].Text;
CheckBox chkAdmin = (CheckBox)row.Cells[2].Controls[0];
CheckBox chkUser = (CheckBox)row.Cells[3].Controls[0];
CheckBox chkgen = (CheckBox)row.Cells[4].Controls[0];
List<string> roles=new List<string>();
if (chkAdmin.Checked)
roles.Add("Admin");
if (chkUser.Checked)
roles.Add("DPAO User");
if (chkgen.Checked)
roles.Add("GeneralUser");
if (Roles.GetRolesForUser(username).Length > 0)
{
Roles.RemoveUserFromRoles(username, Roles.GetRolesForUser(username));
}
if (roles.Count > 0)
{
Roles.AddUserToRoles(username, roles.ToArray());
}
BindGridviewData();
}
}
protected void GridView1_RowDataBound1(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
CheckBox c0 = (CheckBox)e.Row.Cells[0].Controls[0];
CheckBox c2 = (CheckBox)e.Row.Cells[2].Controls[0];
CheckBox c3 = (CheckBox)e.Row.Cells[3].Controls[0];
CheckBox c4 = (CheckBox)e.Row.Cells[4].Controls[0];
c0.Enabled=c2.Enabled =c3.Enabled=c4.Enabled= true;
}
}
protected void cmdDelete_Click1(object sender, EventArgs e)
{
foreach (GridViewRow row in GridView1.Rows)
{
CheckBox chk = (CheckBox)row.Cells[0].Controls[0];
if (chk.Checked)
{
string username = row.Cells[1].Text;
Membership.DeleteUser(username);
BindGridviewData();
}
}
}
Related
I have a radiobuttonlist in a gridview in EditItemTemplate. When i click update in a Row the RBL is correctly displayed with his selected value 1 . But if i click the next ROW, like the AlternatingRowStyle, the RBL is displayed but without his selected value 2
The html:
<asp:GridView ID="GVDER" runat="server" AutoGenerateColumns="False" ShowHeaderWhenEmpty="True" DataKeyNames="DERINS,DERANA"
OnRowCommand="GVDER_RowCommand"
OnRowEditing="GVDER_RowEditing"
OnRowUpdating="GVDER_RowUpdating"
OnRowCancelingEdit="GVDER_RowCancelingEdit"
OnRowDeleting="GVDER_RowDeleting"
OnRowDataBound="GDVER_RowDataBound"
AllowSorting="True"
CellPadding="4"
ForeColor="#333333"
GridLines="None"
AllowPaging="true"
PageSize="8">
<asp:TemplateField >
<HeaderTemplate>
<asp:Label ID="lblHIVA" style="text-align:center" runat="server" Text="IVA" ></asp:Label>
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="lblIva" runat="server" Text='<%# Eval("DERIVA") %>' width="50px" ></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:RadioButtonList ID="RBLIva" runat="server" RepeatDirection="Horizontal" width="250px">
<asp:ListItem style="margin-right:20px;text-indent:5px" Value="0.0"> 0% </asp:ListItem>
<asp:ListItem style="margin-right:20px;text-indent:5px" Value="10.5"> 10,5% </asp:ListItem>
<asp:ListItem style="margin-right:20px;text-indent:5px" Value="21.0" > 21% </asp:ListItem>
</asp:RadioButtonList>
</EditItemTemplate>
<ItemStyle HorizontalAlign="Right" />
</asp:TemplateField>
In the CodeBehind:
public partial class derivacion_listado_actualizable : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Request.IsAuthenticated)
{
Response.Redirect("~/Account/Login.aspx");
}
if (!IsPostBack)
{
CargarGridView();
}
}
protected void CargarGridView()
{
DataTable dtbl = new DataTable();
SqlDataAdapter dataAdapter = null;
SqlConnection edo = new SqlConnection();
edo.ConnectionString = ConfigurationManager.ConnectionStrings["JuncalCon"].ConnectionString;
try
{
edo.Open();
using (SqlCommand com = edo.CreateCommand())
{
com.CommandText = "Select * FROM DERAUX Where DERVAL ='N' ";
dataAdapter = new SqlDataAdapter(com.CommandText, edo);
dataAdapter.Fill(dtbl);
if(dtbl.Rows.Count >0)
{
GVDER.DataSource = dtbl;
GVDER.DataBind();
}
}
}
catch /*...*/
}
protected void GDVER_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if (e.Row.RowState == DataControlRowState.Edit)
{
decimal IvaValue = (decimal)DataBinder.Eval(e.Row.DataItem, "DERIVA");
RadioButtonList rb = (RadioButtonList)e.Row.FindControl("RBLIva");
rb.Items.FindByValue(IvaValue.ToString(CultureInfo.CreateSpecificCulture("en-US"))).Selected = true;
}
}
}
protected void GVDER_RowEditing(object sender, GridViewEditEventArgs e)
{
lblSuccess.Text = "";
GVDER.EditIndex = e.NewEditIndex;
CargarGridView();
}
What im doing wrong..? thx in advance.
The solution is in this post
How to check for combined RowState 'Altering | Edit' in RowDataBound?
The e.Row.RowState can take
Alternate
Edit
Insert
Normal
Selected
Also Alternate con combine with other states.
On a RadGrid I can use the CommandItemTemplate to define my own buttons for, in my case, Save and Cancel the edit (like below)
<CommandItemTemplate>
<div style="padding: 5px 5px;">
<asp:LinkButton ID="btnUpdateEdited" runat="server" CommandName="UpdateEdited">Update</asp:LinkButton>
<asp:LinkButton ID="btnCancel" runat="server" CommandName="CancelAll">Cancel editing</asp:LinkButton>
</div>
</CommandItemTemplate>
On the code behind, I set up the ItemCommand.
> protected void RadGrid1_ItemCommand(object sender, GridCommandEventArgs e)
{
if (e.CommandName.CompareTo("UpdateEdited") == 0)
{
var commandItem = ((GridCommandItem)e.Item);
//Updade code here.
}
}
How can I access the modified row with the modified fields so I can perform an updade?
You should have them in command item and you can access them like this:
GridDataItem item = (GridDataItem)e.Item;
string value = item["ColumnUniqueName"].Text;
Is this what you want ? Just a sample you might need to modify it..
.aspx
<telerik:RadGrid ID="rg" runat="server" AutoGenerateColumns="false"
OnNeedDataSource="rg_NeedDataSource" OnItemCommand="rg_ItemCommand"
MasterTableView-CommandItemDisplay="Top" OnItemDataBound="rg_ItemDataBound">
<MasterTableView EditMode="InPlace">
<CommandItemTemplate>
<div style="padding: 5px 5px;">
<asp:LinkButton ID="btnUpdateEdited" runat="server"
CommandName="UpdateEdited">Update</asp:LinkButton>
<asp:LinkButton ID="btnCancel" runat="server"
CommandName="CancelAll">Cancel editing</asp:LinkButton>
</div>
</CommandItemTemplate>
<Columns>
<telerik:GridTemplateColumn>
<ItemTemplate>
<asp:Label ID="lbl" runat="server"
Text='<%# Eval("A") %>' />
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txt" runat="server"
Text='<%# Eval("A") %>'></asp:TextBox>
</EditItemTemplate>
</telerik:GridTemplateColumn>
<telerik:GridTemplateColumn>
<ItemTemplate>
<asp:LinkButton ID="btnEdit" runat="server" Text="Edit"
CommandName="Edit"></asp:LinkButton>
</ItemTemplate>
<EditItemTemplate> </EditItemTemplate>
</telerik:GridTemplateColumn>
</Columns>
</MasterTableView>
</telerik:RadGrid>
.cs
protected void Page_Load(object sender, EventArgs e)
{
// Check
if (!IsPostBack)
{
// Variable
DataTable dt = new DataTable();
dt.Columns.Add("A");
dt.Rows.Add("A1");
// Check & Bind
if (dt != null)
{
// Viewstate
ViewState["Data"] = dt;
rg.DataSource = dt;
rg.DataBind();
dt.Dispose();
}
}
}
protected void rg_NeedDataSource(object sender, GridNeedDataSourceEventArgs e)
{
rg.DataSource = ViewState["Data"] as DataTable;
}
protected void rg_ItemCommand(object sender, GridCommandEventArgs e)
{
// Check
if (e.CommandName == "UpdateEdited")
{
// Variable
DataTable dt = new DataTable();
dt.Columns.Add("A");
// Loop All
foreach (GridEditableItem item in rg.Items)
{
// Find Control
TextBox txt = item.FindControl("txt") as TextBox;
// Check & Add to DataTable
if (txt != null) dt.Rows.Add(txt.Text.Trim());
}
// Check
if (dt != null && dt.Rows.Count > 0)
{
// Set Viewstate
ViewState["Data"] = dt;
// Bind
rg.DataSource = dt;
rg.DataBind();
// Dispose
dt.Dispose();
}
}
else if (e.CommandName == "CancelAll")
{
// Clear Edit Mode
rg.MasterTableView.ClearChildEditItems();
// Rebind
rg.Rebind();
}
}
protected void rg_ItemDataBound(object sender, GridItemEventArgs e)
{
// Check
if (e.Item is GridCommandItem)
{
// Find Control
LinkButton btnUpdateEdited = e.Item.FindControl("btnUpdateEdited") as LinkButton;
LinkButton btnCancel = e.Item.FindControl("btnCancel") as LinkButton;
// Get is Edit Mode ?
if (rg.EditIndexes.Count > 0)
{
if (btnUpdateEdited != null) btnUpdateEdited.Visible = true;
if (btnCancel != null) btnCancel.Visible = true;
}
else
{
if (btnUpdateEdited != null) btnUpdateEdited.Visible = false;
if (btnCancel != null) btnCancel.Visible = false;
}
}
}
I have a gridView with 5 columns with Edit and Delete button on each row of GridView. Once an Edit button a particular row is clicked , I want to disable the edit and delete buttons on rest of the rows.
Below is my aspx
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" ShowFooter="True" EnableModelValidation="True" onrowdatabound="GridView1_RowDataBound" onrowcommand="GridView1_RowCommand" onrowdeleting="GridView1_RowDeleting" EditRowStyle-ForeColor="Aqua" onrowediting="GridView1_RowEditing" >
<asp:TemplateField HeaderText="Item#" >
<ItemTemplate>
<asp:Label ID="Item#" runat="server" Text='Label' ></asp:Label>
</ItemTemplate>
</asp:TemplateField>
..........
<asp:TemplateField >
<ItemTemplate>
<asp:Button ID="btnEdit" runat="server" CausesValidation ="false" Font-Size="Smaller" CommandName="Edit" Text="Edit" CommandArgument='<%# DataBinder.Eval(Container, "RowIndex") %>' Width="35px"/>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField >
<ItemTemplate>
<asp:Button ID="btnDelete" runat="server" CssClass="GridButton" CausesValidation="False" CommandName="Delete" Font-Size="Smaller" Text="Delete" CommandArgument='<%# DataBinder.Eval(Container, "RowIndex") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Delete")
{
int x = Convert.ToInt32(e.CommandArgument.ToString());
txtLineItemNumber.Text = (x + 1).ToString();
}
else
{
int x = Convert.ToInt32(e.CommandArgument.ToString());
foreach (GridViewRow row in GridView1.Rows)
{
if (row.RowIndex != x)
{
Button editButton = (Button)row.FindControl("btnEdit");
editButton.Enabled = false;
Button deleteButton = (Button)row.FindControl("btnDelete");
deleteButton.Enabled = false;
}
else
{
Button deleteButton = (Button)row.FindControl("btnDelete");
deleteButton.Text = "Cancel";
e.CommandName = "Cancel"; --- This is not possible...what should I do so that the Command Name is changed to Cancel and it does the cancel operation.
}
} }
}
Please help me to get it working.....
The approach you are taking will work fine. However the CommandArgument which is set in your markup CommandArgument='<%# DataBinder.Eval(Container, "RowIndex") %>' is not a reference to the Button itsself but the index of the GridView row the Button resides in.
You will need to retrieve the index from the CommandArgument in the RowCommand event and then enable/disable all buttons on other rows like so:
void gridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
switch (e.CommandName.ToLower())
{
case "edit":
{
int rowIndex = Convert.ToInt32(e.CommandArgument);
foreach (GridViewRow row in gridView1.Rows)
{
if (row.RowIndex != rowIndex)
{
Button editButton = (Button)row.FindControl("btnEdit");
editButton.Enabled = false;
Button deleteButton = (Button)row.FindControl("btnDelete");
deleteButton.Enabled = false;
}
}
}break;
}
}
Edit (based on comment)
Try moving the code that modifies the delete button to the RowEditing event handler like so:
void gridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
gridView1.EditIndex = e.NewEditIndex;
DataBind();
Button deleteButton = (Button)gridView1.Rows[e.NewEditIndex].FindControl("btnDelete");
deleteButton.Text = "Cancel";
deleteButton.CommandName = "Cancel";
}
void gridView1_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
gridView1.EditIndex = -1;
DataBind();
}
Hope this helps.
You could use javascript, outlined here, http://www.krissteele.net/blogdetails.aspx?id=92 . Add logic to not disable for the current row.
Edit: My object is defined as below. I passed it into GridView1.
public class UserTestorViewModel
{
public string Username {get;set;}
public string Password {get;set;}
public Label SuiteName {get;set;}
}
I have GridView bound to a customized List<UserTestorViewModel>:
this.GridView1.DataSource = utViewModelList;
this.GridView1.DataBind();
and in the .aspx I have
<asp:TemplateField HeaderText="LoginName">
<ItemTemplate>
<asp:Label ID="LoginName" runat= "server" Text= '<%# ((ViewModels.UserTestorViewModel)Container.DataItem).User.userName %> '></asp:Label>
</ItemTemplate>
</asp:TemplateField>
this works because ViewModels.UserTestorViewModel.User.userName is string, but
<asp:TemplateField HeaderText="SuiteName">
<ItemTemplate>
<%# ((ViewModels.UserTestorViewModel)Container.DataItem).SuiteName %>
</ItemTemplate>
</asp:TemplateField>
because ViewModels.UserTestorViewModel.SuiteName is Label from System.Web.UI.WebControls
So how to bind a System.Web.UI.WebControls to <ItemTemplate> NOT the Text of the System.Web.UI.WebControls
You may place a Placeholder control in ItemTemplate and put your label control to it on the RowCreated event of the GridView:
protected void Page_Init(object sender, EventArgs e)
{
GridView1.RowCreated += new GridViewRowEventHandler(GridView1_RowCreated);
}
void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var dataItem = (KeyValuePair<int, Label>)e.Row.DataItem;
var nameLabelPlaceholder = e.Row.FindControl("NameLabelPlaceholder") as PlaceHolder;
if (nameLabelPlaceholder != null)
{
nameLabelPlaceholder.Controls.Add(dataItem.Value);
}
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GridView1.DataSource = GetGridViewDataSource();
GridView1.DataBind();
}
}
private object GetGridViewDataSource()
{
return (from item in Enumerable.Range(1, 10)
select new KeyValuePair<int, Label>(item, new Label() { ID = string.Format("NameLabel_{0}", item), Text = string.Format("Item #{0}", item), ForeColor = System.Drawing.Color.Red }))
.ToDictionary(kvp1 => kvp1.Key, kvp2 => kvp2.Value);
}
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" DataKeyNames="Key">
<Columns>
<asp:BoundField HeaderText="Id" DataField="Key" />
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<asp:PlaceHolder runat="server" ID="NameLabelPlaceholder" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
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.