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;
Related
I have a nested repeater and there is a radiobutton in the inner one ( rptrSubscriptions ). What I want to do is to highlight the radio button that is selected and unhighlight the previous one .
There must be only one radio button selected between all of the radio buttons in the outer repeater .I also need to save the itemID of the selected one in a hidden field.
I have developed a method with the name of HighlightSubscription that will be called when user clicks on the radio button (OnCheckedChanged="HighlightSubscription") .
The problem is this, the system doesn't recognize rptrSubscriptions in HighlightSubscription method, I tried to use findcontrol but unfortunately there is no access to e.items in this method.
I also defined rptrSubscriptions as a public variable but it will be null too in this method.
I have copied the source of HighlightSubscription from HighlightBox that is a radio button inside a single repeater and it works fine as its definition is inside the designer,
but for the nested repeater the definition cant be in the designer as the system automatically removes it in compile time.
Any suggestion is highly appreciated.
protected void rptrSubscriptionGroups_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
Repeater rptrSubscriptions = (Repeater)e.Item.FindControl("rptrSubscriptions");
if (rptrSubscriptions != null)
{
RepeaterItem item = e.Item;
if (e.Item.ItemType == (ListItemType.Item) || e.Item.ItemType == (ListItemType.AlternatingItem))
{
DataTable SubscriptionTbl = SubscriptionsBind(SelectedLanguageID, SelectedPlatformID, SelectedCurrencyID, SelectedGroupID, 1);
rptrSubscriptions.DataSource = SubscriptionTbl;
rptrSubscriptions.DataBind();
}
}
}
protected void HighlightSubscription(object source, EventArgs e)
{
//find previous selected row
if (hiddenSelectedSubscriptionRowIndex.Value.Length > 0)
{
int rowIndex = int.Parse(hiddenSelectedSubscriptionRowIndex.Value);
//Repeater rptrSubscriptions = (Repeater)e.Item.FindControl("rptrSubscriptions");
RepeaterItem item = rptrSubscriptions.Items[rowIndex];
if (rptrSubscriptions != null)
{
// Uncheck Old Radio Button
RadioButton rbOld = (RadioButton)item.FindControl("rbBox");
rbOld.Attributes.CssStyle.Add("border-color", "lightgray");
rbOld.Attributes.CssStyle.Add("border-width", "1px");
rbOld.Checked = false;
}
}
RadioButton rb = source as RadioButton;
int CurrentrepeaterItemIndex = ((RepeaterItem)rb.NamingContainer).ItemIndex;
// save current row index in a hiddden field
hiddenSelectedSubscriptionRowIndex.Value = CurrentrepeaterItemIndex.ToString();
}
<asp:Repeater ID="rptrSubscriptionGroups" runat="server" OnItemDataBound="rptrSubscriptionGroups_ItemDataBound" OnItemCommand="rptrSubscriptionGroups_ItemCommand">
<ItemTemplate>
<asp:Repeater ID="rptrSubscriptions" runat="server" OnItemDataBound="rptrSubscriptions_ItemDataBound" OnItemCommand="rptrSubscriptions_ItemCommand">
<ItemTemplate>
<asp:RadioButton ID="rbSubscription" runat="server" OnCheckedChanged="HighlightSubscription" AutoPostBack="true"/>
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
A little edit from me you can try this one :
protected void HighlightSubscription(object source, EventArgs e)
{
Repeater rptrSubscriptions = new Repeater();
foreach (RepeaterItem a in rptrSubscriptionGroups.Items)
{
rptrSubscriptions = (Repeater)a.FindControl("rptrSubscriptions");
}
//find previous selected row
if (hiddenSelectedSubscriptionRowIndex.Value.Length > 0)
{
int rowIndex = int.Parse(hiddenSelectedSubscriptionRowIndex.Value);
//Repeater rptrSubscriptions = (Repeater)e.Item.FindControl("rptrSubscriptions");
RepeaterItem item = rptrSubscriptions.Items[rowIndex];
if (rptrSubscriptions != null)
{
// Uncheck Old Radio Button
RadioButton rbOld = (RadioButton)item.FindControl("rbBox");
rbOld.Attributes.CssStyle.Add("border-color", "lightgray");
rbOld.Attributes.CssStyle.Add("border-width", "1px");
rbOld.Checked = false;
}
}
RadioButton rb = source as RadioButton;
int CurrentrepeaterItemIndex = ((RepeaterItem)rb.NamingContainer).ItemIndex;
// save current row index in a hiddden field
hiddenSelectedSubscriptionRowIndex.Value = CurrentrepeaterItemIndex.ToString();
}
Something like this:
protected void rptrSubscriptionGroups_ItemDataCreated(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
RepeaterItem item = e.Item;
RadioButton rb = (RadioButton)item.FindControl("rbSubscription");
rb.AutoPostBack = true;
rb.CheckedChanged += new EventHandler(rb_CheckChanged);
}
}
private void rb_CheckChanged(object sender, EventArgs e)
{
RadioButton rb = (RadioButton)sender;
if(rb.Checked == true){
HighlightSubscription();
}
}
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
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
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var firstCell = e.Row.Cells[0];
firstCell.Controls.Clear();
firstCell.Controls.Add(new HyperLink { NavigateUrl = "ser_job_status1.aspx?Complaint_No = " + firstCell.Text, Text = firstCell.Text, Target = "_blank" });
}
}
}
I have used this to include hyperlink in my gridview.If that link is clicked it may take me to ser_job_status1.aspx where Complaint_No is my table field name.
is it correct...
If correct how do i get that Complaint_No value in the Label field of my second page..
Kindly help me to figure it out...
I use C# in code behind
In ser_job_status1.aspx page:
string strComplaintNo=Request.Querystring["Complaint_No"];
label1.text=strComplaintNo
or
Use Session rowdatabound page
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var firstCell = e.Row.Cells[0];
Session["ComplaintNo"]=firstCell.text;
firstCell.Controls.Clear();
firstCell.Controls.Add(new HyperLink { NavigateUrl = "ser_job_status1.aspx?Complaint_No = " + firstCell.Text, Text = firstCell.Text, Target = "_blank" });
}
}
}
In ser_job_status1.aspx page:
label1.text=convert.tostring(Session["ComplaintNo"]);
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;
}
}
}