linkButton Click Event in Grid View not firing when adding though Bound Fields in a loop in GridView - asp.net

Hi,Here i am trying to implement the linkButton click event in a
gridview through code behind using the BoundField Class in gridview.
when i trying to add the individual BoundField values Directly to grid
as a column in page_Load and binding the linkbutton in
RowDataBoundEvent of the row of cell with linkbutton click event, it
is firing the linkButton Click event well with the following code.
protected void Page_Load(object sender,EventArgs e)
{
BoundField bfield = new BoundField();
bfield.HeaderText = "EmpName";
bfield.DataField = "EmpName";
gridView.Columns.Add(bfield);
BoundField bfield1 = new BoundField();
bfield1.HeaderText = "Monday";
bfield1.DataField = "Monday";
gridView.Columns.Add(bfield1);
}
and in on RowDataBound Event i have wrote
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
LinkButton lnkViews = new LinkButton();
lnkViews.ID = "lnkViews";
lnkViews.Text = (e.Row.DataItem as DataRowView).Row["Monday"].ToString();
lnkViews.Click += new EventArgs(linkButton_ClickAction);
e.Row.Cells[2].Controls.Add(lnkViews);
}
}
protected void linkButton_ClickAction(object sender, EventArgs e)
{
LinkButton lnkView = (sender as LinkButton);
GridViewRow row = (lnkView.NamingContainer as GridViewRow);
string id = lnkView.CommandArgument;
string name = row.Cells[0].Text; this.ModalPopupExtender1.Show();
}
But when i trying to add the above BoundFields by looping based on the
table columns count like this, in page_Load event, the event is not
firing.
protected void Page_Load(object sender,EventArgs e)
{
DataTable dtTable = new DataTable();
dtTable= BindGrid();
BoundField boundField;
for (int i = 0; i < dtTable.Columns.Count; i++)
{
string ColumnValue = dtTable.Columns[i].ColumnName;
boundField = new BoundField();
boundField.HeaderText = ColumnValue;
boundField.DataField = ColumnValue;
gridView.Columns.Add(boundField);
}
}
when we creating the BoudnField event using the above code in a loop
based on dataSource columns count, it doesn't firing linkbutton event. why?

as per my understanding you are trying to form grid dynamically.
One thing is bound fields will not support for bubbled events. So better replace them with template fields that will meets your requirement.
You need to assign click event in InstantiateIn method by defining ITemplate interface.
OnRowDataBound event doesn't comes into picture.
below is example for your reference.
http://forums.asp.net/t/1001702.aspx

Related

asp.net set command argument

I am using OnRowDataBound to automatically add a link button to my grid view that looks like this. The problem I am having is setting the command argument.
<asp:LinkButton ID = "lnkDelete" Text = "Delete" CommandArgument = '<%# Eval("Value") %>' runat = "server" OnClick = "DeleteFile" />
Below is the code that adds the links. I set the command argument to Eval("Value") but that doesn't work. Here is a link to the original code that I'm trying to change so it is dynamic.
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
LinkButton lnkView = new LinkButton();
lnkView.ID = "lnkDelete";
lnkView.Text = "Delete";
lnkView.Click += DeleteFile;
lnkView.CommandArgument = Eval("Value");
e.Row.Cells[1].Controls.Add(lnkView);
}
RowDataBound is not the right event to add controls dynamically because they need to be re-created on every consecutive postback. RowDataBound is triggered only if you call GridView.DataBind().
So use RowCreated instead, but assign the CommandArgument value in RowDataBound and don't use Eval("Value") but the actual datasource which you get from e.Row.DataItem.
Something like this should work:
protected void OnRowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
LinkButton lnkView = new LinkButton();
lnkView.ID = "lnkDelete";
lnkView.Text = "Delete";
lnkView.Click += DeleteFile;
e.Row.Cells[1].Controls.Add(lnkView);
}
}
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
LinkButton lnkView = (LinkButton)e.Row.FindControl("lnkDelete");
var rowView = (DataRowView)e.Row.DataItem;
lnkView.CommandArgument = rowView.Row.Field<string>("Value");
}
}
If this throws an exception at runtime you need to change (DataRowView)e.Row.DataItem to the actual datasource which you can get from the debugger.
Edit: as commented it is a ListItem and you want to use it's Value property:
var item = (ListItem) e.Row.DataItem;
lnkView.CommandArgument = item.Value;

Retrieving a Dynamically Generated TextBox Content in a GridView in ASP.NET

I have the following RowDataBound method for GridView2
protected void GridView2_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
List<TextBox> list = new List<TextBox>();
if (ViewState["Table"] != null)
Assessments = (DataTable)ViewState["Table"];
int count = 1;
foreach (DataRow row in Assessments.Rows)
{
TextBox txt = new TextBox();
txt.ID = "AsTxt";
txt.Text = string.Empty;
txt.TextChanged += OnTextChanged;
e.Row.Cells[count].Controls.Add(txt);
count += 2;
listd.Add((e.Row.DataItem as DataRowView).Row[0].ToString() + "Txt");
}
}
}
And the following event (Button Click) to retrieve whatever written in the text box in the GridView
protected void CalculateBtn_Click(object sender, EventArgs e)
{
GridViewRow rr = GridView2.Rows[0];
TextBox rrrr = (rr.FindControl("AsTxt") as TextBox);
ClientScript.RegisterStartupScript(this.GetType(), "alert", "alert('" + rrrr.Text + "')", true);
}
I always get NullReferenceException. That mean the TextBox object (rrrr) is null always. I am sure that the text object sits in GridView2.Rows[0].
Why is this happening?
This is known issue with the Dynamical created controls in asp. So if you want to use the created control on your postback then I suggest that you declare your controls outside the page_int and do your initialization in the init then use them with their name instead of find control.
Look at this blog this might help you
http://techbrij.com/retrieve-value-of-dynamic-controls-in-asp-net

Dynamic template field in grdivew post back values

//Bedlow is the page_load code to add dynamic controls in page load. and load of page_load
gvSecond 's dynamic template fields will be added.I want to know why the dot is appended on each postback values
protected void Page_Load(object sender, EventArgs e)
{
gvFirst.DataSource = GetData("select top 10 * from Project_Master");
gvFirst.DataBind();
}
//gvFirst has gvSecond and on rowdatabound of the gvFirst gvSecond populated with dynamic template fields. and all the template fields has the TextBoxtes in it
protected void gvFirst_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
//below code to generate dynamic template column
gvFirst.DataSource = GetData("select top 10 * from Project_Master");
gvFirst.DataBind();
//Added dynamic controls in gvSecond
protected void gvFirst_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
string customerId = gvFirst.DataKeys[e.Row.RowIndex].Value.ToString();
GridView gvSecond = e.Row.FindControl("gvSecond") as GridView;
DataTable dt= GetData1(Convert.ToInt32(customerId));
foreach (DataColumn col in dt.Columns)
{
//Declare the bound field and allocate memory for the bound field.
TemplateField bfield = new TemplateField();
//Initalize the DataField value.
bfield.HeaderTemplate = new GridViewTemplate(ListItemType.Header, col.ColumnName);
//Initialize the HeaderText field value.
bfield.ItemTemplate = new GridViewTemplate(ListItemType.Item, col.ColumnName);
//Add the newly created bound field to the GridView.
gvSecond.Columns.Add(bfield);
}
TotalColumns = dt.Columns.Count;
gvSecond.DataSource = dt;
gvSecond.DataBind();
}
}
}
//This is used to add the dynamic template in gvSecond.Now when I click on button textbox values appended with postback values and older values seperated by dot(.)
You need to wrap the code in Page_Load in if(!IsPostback){}:
EDIT :
Edited to create second grid at postback.
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
gvFirst.DataSource = GetData("select top 10 * from Project_Master");
gvFirst.DataBind();
}
else
{
CreateSecondGridView();
}
}
And your Rowdatabound may look like this:
protected void gvFirst_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
CreateSecondGridView();
}
protected void CreateSecondGridView()
{
foreach(GridViewRow row in gvFirst.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
string customerId = gvFirst.DataKeys[row.RowIndex].Value.ToString();
GridView gvSecond = row.FindControl("gvSecond") as GridView;
DataTable dt= GetData1(Convert.ToInt32(customerId));
foreach (DataColumn col in dt.Columns)
{
//Declare the bound field and allocate memory for the bound field.
TemplateField bfield = new TemplateField();
//Initalize the DataField value.
bfield.HeaderTemplate = new GridViewTemplate(ListItemType.Header, col.ColumnName);
//Initialize the HeaderText field value.
bfield.ItemTemplate = new GridViewTemplate(ListItemType.Item, col.ColumnName);
//Add the newly created bound field to the GridView.
gvSecond.Columns.Add(bfield);
}
TotalColumns = dt.Columns.Count;
gvSecond.DataSource = dt;
gvSecond.DataBind();
}
}
}

Accessing dynamically generated controls Object reference not set to an instance of an object

I am adding controls dynamically to my page on the basis on a condition.There's a button in these controls, to which i have attached an event handler as well for click event.Now in this event handler, i am trying to access my dynamically generated controls, but getting an exception. Here's my code:
protected void Page_Load(object sender, EventArgs e)
{
String Method = Request.QueryString["Method"];
String Tag = Request.QueryString["Tag"];
if (Method=="ADD" && Tag=="METHOD")
{
//6
TableCell cell11 = new TableCell();
cell11.Text = "NEXTLEVEL";
TableCell cell12 = new TableCell();
TextBox txt6 = new TextBox();
txt6.ID = "txt6";
cell12.Controls.Add(txt6);
TableRow row6 = new TableRow();
row6.Cells.Add(cell11);
row6.Cells.Add(cell12);
container.Rows.Add(row6);
TableCell cell14 = new TableCell();
Button submit = new Button();
submit.ID = "SubmitButton";
submit.Text = "Submit";
submit.Click += new EventHandler(submit_Click);
cell14.Controls.Add(submit);
TableRow row7 = new TableRow();
row7.Cells.Add(cell14);
container.Rows.Add(row7);
}
void submit_Click(object sender, EventArgs e)
{
ModifySessionAnalyzer msa = new ModifySessionAnalyzer();
TextBox txt6= (TextBox)Page.FindControl("txt6") as TextBox;
##String message = txt6.Text;##
}
TableCell cell12 = new TableCell();
TextBox txt6 = new TextBox();
txt6.ID = "txt6";
cell12.Controls.Add(new TextBox());
This is wrong, you are not adding the txt6 control to the cell, instead you are adding a new textBox...
Dynamically added controls should be added in the Page_Init method not Page_Load. If they are added into Page_Load they won't be added to the control tree and you'll get issues - i.e. they won't participate in ViewState correctly.
So (TextBox)Page.FindControl("txt6") could fail as the text box is no longer in the control tree
This could be the source of your issue.
Further explanation
Your code should be
protected void Page_Init(object sender, EventArgs e)
{
//.. your code goes here
}
NOT
protected void Page_Load(object sender, EventArgs e)
{
//.. your code
}
It's normal practice to use Page_Load so it's just an easy habit for people but when using dynamic controls then this is the exception
When i say dynamic controls - it's anything when you are added controls on the fly rather than declaring them in your page. Look for anything where you are going Controls.Add

How to get the value of selected row using radiobutton in gridview in a button click

i need to get the value of the selected row of radiobutton in the gridview. the selected value is assigned to a textbox. my code is
protected void lnBTNDone_Click(object sender, EventArgs e)
{
GridViewRow gvRow = grdEventDetails.SelectedRow;
txtEventId.Text = gvRow.Cells[0].Text;
}
the problem is the gvRow value is assigned as null .
the linkbutton is not inside gridview. the gridview n linkbutton and the textbox are inside the user controls.
You can always get the GridViewRow via the sender's NamingContainer:
protected void lnBTNDone_Click(object sender, EventArgs e)
{
LinkButton lnBTNDone = (LinkButton)sender;
GridViewRow row = (GridViewRow)lnBTNDone.NamingContainer;
txtEventId.Text = row.Cells[0].Text;
}
Assuming that the LinkButton is in the selected row.
Btw, i'm yet not sure why SelectedRow is null there, maybe because the GridView's SelectedIndexChanged event is triggered after the LinkButton's click event.
protected void lnBTNDone_Click(object sender, EventArgs e)
{
for (int i = 0; i < grdEventDetails.Rows.Count; i++)
{
RadioButton rb = (grdEventDetails.Rows[i].FindControl("grdRdo")) as RadioButton;
if (rb.Checked == true)
{
txtEventId.Text = grdEventDetails.Rows[i].Cells[1].Text;
}
}
}

Resources