remove eventhandler on ItemTemplate - c#

I want to remove the event handler of an ItemTemplate in asp .net. Here is the asp code
<ItemTemplate>
<asp:RadioButton runat="server" ID="rdbAnswer" GroupName="Group" AutoPostBack="True"
OnCheckedChanged="rdbAnswer_CheckedChanged" />
</ItemTemplate>
I want to remove the checkedchanged event on code behind. How can i do this ?

Use -= to remove an event handler. You could do that in RowCreated:
protected void gridView1_RowCreated(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
RadioButton rdbAnswer = (RadioButton)e.Row.FindControl("rdbAnswer");
if(YourCondition)
{
// Remove event handler
rdbAnswer.CheckedChanged -= new EventHandler(rdbAnswer_CheckedChanged);
// maybe you also want to set rdbAnswer.AutoPostBack="false" to prevent the postback
}
}
}
Remember to register the RowCreated event handler:
<asp:GridView ID="gridView1" OnRowCreated="gridView1_RowCreated" runat="server">

Related

LinkButton.Click event not firing when dynamically attached in GridView row databound

I have a asp:GridView inside of an asp:UpdatePanel, which has a column of asp:LinkButton controls.
On the row databound event, the LinkButton gets it's click event handler assigned.
I've tried every way I could find to wire up the click even and none of the events ever fire.
Am I doing something wrong?
aspx:
<asp:UpdatePanel ID="MainUpdatePanel" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Label ID="lblTest" Text="test" runat="server" />
<asp:GridView ID="gvClientsArchive" runat="server" AllowSorting="true" DataSourceID="dsClients"
OnRowDataBound="gvClientsArchive_RowDataBound" SkinID="gvList"
AllowPaging="true" PageSize="25" Visible="false">
...
Code behind:
protected void gvClientsArchive_RowDataBound(object sender, GridViewRowEventArgs e)
{
...
int company_id = int.Parse(drvRow["company_id"].ToString());
LinkButton lnkRestore = (LinkButton)e.Row.FindControl("lnkRestore");
lnkRestore.Click += new System.EventHandler(this.doRestore);
Button handler code:
private void doRestore(object sender, EventArgs e)
{
lblTest.Text = "restore clicked";
}
I've also tried:
protected void gvClientsArchive_RowDataBound(object sender, GridViewRowEventArgs e)
{
...
LinkButton lnkRestore = (LinkButton)e.Row.FindControl("lnkRestore");
lnkRestore.Click += delegate
{
lblTest.Text = "restore clicked";
};
RowDataBound is inappropriate if you want to register event handlers. Use RowCreated:
protected void gvClientsArchive_RowCreated(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
LinkButton lnkRestore = (LinkButton)e.Row.FindControl("lnkRestore");
lnkRestore.Click += new System.EventHandler(this.doRestore);
}
}
RowDataBound is triggered only if you Databind the grid not on every postback which is needed since all controls are disposed at the end of the page's lifecycle. It's also too late.
If you use TemplateFields it's easier to register the handler declaratively on the aspx.

RowDataBound not acting the way I expect

I have a Gridview with an ImageButton that should become visible for the selected row only. I'm doing this in the OnRowDataBound event, but it doesn't work.
protected void OnRowDataBoundMS(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if ((e.Row.RowState & DataControlRowState.Edit) > 0)
{
// some working code that handles the edit mode
}
else if (Gridview1.SelectedValue != null)
{
ImageButton ImgBut1 = e.Row.FindControl("ButtonUp") as ImageButton;
ImgBut1.Visible = true;
}
}
}
My gridview looks like this:
<asp:GridView runat="server"
ID="Gridview1"
DataSourceID="Milestones"
DataKeyNames="ID"
AutoGenerateColumns="false"
OnRowEditing="OnRowEditing"
OnRowDataBound="OnRowDataBoundMS"
OnSelectedIndexChanged="OnSelectedIndexChangedMS">
...
<asp:templatefield HeaderText="Order" ItemStyle-HorizontalAlign="center">
<ItemTemplate>
<asp:ImageButton ID="ButtonUp" runat="server" OnClick ="OrderUp" ImageUrl="img/up.png" Visible="false"/>
</ItemTemplate>
</asp:templatefield>
I spent the last 3 hours on this and I start to freak out. Any hints on this? Martin
The other alternative is to use the SelectedIndexChanged event if you are using the Select command option:
protected void OnSelectedIndexChangedMS(object sender, EventArgs e)
{
foreach (GridViewRow row in GridView1.Rows)
{
Control ctl = row.FindControl("ButtonUp");
ctl.Visible = (row.RowState & DataControlRowState.Selected) != 0;
}
}
Something like that; RowDataBound may fire before the selected index gets updated (not sure about that...).
You can detect the selected row in the RowDataBound event handler with the RowState property, the same way you detect the edit row:
if ((e.Row.RowState & DataControlRowState.Selected) != 0)
{
...
}
An alternative is to set the Visible property of the ImageButton in the markup, with a data-binding expression:
<asp:ImageButton runat="server" Visible='<%# ((Container as GridViewRow).RowState & DataControlRowState.Selected) != 0 %>' ... />
Note: make sure that you call GridView1.DataBind() in the SelectedIndexChanged event handler, in order to refresh the content of the GridView.
I guess the key comment is what Brian Mains said about the RowDataBound firing before the selected Index gets updated. I can't prove this to be generally right, but it seems so. Therefore all attempts, even following ConnersFan suggestions didn't worked out. I did what Brian suggested and used the SelectedIndexChanged event handler, but without looping through all rows. The solution is actually quite simple:
protected void OnSelectedIndexChangedMS(object sender, EventArgs e)
{
Gridview1.DataBind();
ImageButton ImgBut1 = Gridview1.SelectedRow.FindControl("ButtonUp") as ImageButton;
ImgBut1.Visible = true;
}

FormView.DataItem is null on postback

I am using a LinqDataSource and a FormView with paging enabled on an ASP.NET page. I am trying to access the FormView's DataItem property on PageLoad and I have no trouble on the first page load, but as soon as I use the Next/Prev page button (causing a postback) on the FormView the DataItem property is null, even if there a record showing in the FormView. Any ideas why it works fine on the first page load but not on a postback?
If you're curious what my PageLoad event looks like, here it is:
protected void Page_Load(object sender, EventArgs e)
{
Label lbl = (Label)fvData.FindControl("AREALabel");
if (fvData.DataItem != null && lbl != null)
{
INSTRUMENT_LOOP_DESCRIPTION record = (INSTRUMENT_LOOP_DESCRIPTION)fvData.DataItem;
var area = db.AREAs.SingleOrDefault(q => q.AREA1 == record.AREA);
if (area != null)
lbl.Text = area.AREA_NAME;
}
}
The object you bind to any data-bound control won't be persisted in the page's ViewState
Therefore, on subsequent posts the DataItem property will be null unless you re-bind the control
This property will contain a reference to the object when the control is bound.
Usually you would need to access this property if you want to do something when the objects is bound, so you need to react to the DataBound event
Example:
Output
Code behind
protected void ds_DataBound(object sender, EventArgs e)
{
var d = this.fv.DataItem as employee;
this.lbl.Text = d.lname;
}
ASPX
<asp:LinqDataSource ID="lds" runat="server"
ContextTypeName="DataClassesDataContext"
TableName="employees"
>
</asp:LinqDataSource>
<asp:FormView runat="server" ID="fv" DataSourceID="lds" AllowPaging="true"
OnDataBound="ds_DataBound">
<ItemTemplate>
<asp:TextBox Text='<%# Bind("fname") %>' runat="server" ID="txt" />
</ItemTemplate>
</asp:FormView>
<br />
<asp:Label ID="lbl" runat="server" />
Your data will not be preserved on PostBack. You'll need to rebind the FormView in the PageIndexChanging event using something like:
protected void FormView_PageIndexChanging(object sender, FormViewPageEventArgs e)
{
FormView.PageIndex = e.NewPageIndex;
//rebind your data here
}

Cannot fire the DeleteCommand in a Datalist

I want to fire the Delete Command in Datalist Control .. but it is not firing .. Help please ..
this is my code :
protected void DeleteCommand(object source, DataListCommandEventArgs e)
{
Label2.Text = "hello";
}
and This is my html code :
<asp:DataList ID="DLImages" runat="server" BorderStyle="None"
DataKeyField="fId" RepeatColumns="4"
RepeatDirection="Horizontal" ShowFooter="False" ShowHeader="False"
OnDeleteCommand="DeleteCommand"
onitemdatabound="DLImages_ItemDataBound">
<ItemTemplate>
<asp:ImageButton ID="IBDelete" runat="server" BorderStyle="None" CommandName="Delete" ImageUrl="~/Dashboard/Images/dldelete.png" />
</ItemTemplate>
</asp:DataList>
..
Your code looks like OK to me. It should fire the DeleteCommand.
But the problem is that I am sure you are binding the Datalist in your page_load event, but not under If(!IsPostBack) condition. What happens when you hit Delete button is your page_load event fires before your DeleteCommand and it rebinds the DataList and your event is lost
Your page_load event code should look like...
If(!IsPostBack)
{
DataList binding code goes here......
...........................
}
protected void DropDownList2_SelectedIndexChanged(object sender, EventArgs e)
{
// Bind the DataList here....
}

Assign an event to a custom control inside a Repeater control

I have a Repeater control which in some of its cells contains a UserControl which contains a DropDownList. On the ItemDataBound event of the Repeater control I'm assigning an event to the DropDownList like so:
protected void MyRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
...
MyControl myControl = (MyControl)e.Item.FindControl("MyControl01");
myControl.DataSource = myObject;
myControl.DataBind();
myControl.DropDownList.SelectedItemChange += MyMethod_SelectedIndexChanged;
myControl.DropDownList.AutoPostBack = true;
....
}
protected void MyMethod_SelectedIndexChanged(object sender, EventArgs e)
{
//Do something.
}
The event never fires. Please I need help.
Your event is not being raised in a PostBack because your event handler has not been attached (it is only attached during the iteration of the page life-cycle when your repeater is databound).
If you attach your event handler declaratively in the markup such as:
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged" />
</ItemTemplate>
</asp:Repeater>
Then your event handler will be called during PostBacks.
There are two things you can try to see if it will help:
Try binding your MyRepeater on every page request, not just when !IsPostBack.
Bind MyRepeater inside OnInit.
For 1) If your dynamically created controls are created the first time the page loads and then again when postback occurs, ASP.NET will notice that the event raised matches and will fire the event.
For 2) The designer used always place event attachment in OnInit, though it should work fine in OnLoad too.
First make sure your databinding is not resetting your dropdowns.
Here is the code for the control which will nest inside the repeater ItemTemplate
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="ListBoxContainer.ascx.cs" Inherits="OAAF.Common.ListBoxContainer" %>
<asp:ListBox ID="lstFromControl" runat="server" Rows="1" DataTextField="Text" DataValueField="Id" OnSelectedIndexChanged="LstFromControl_SelectedIndexChanged" AutoPostBack="true" />
The code behind for the control which will nest inside the repeater ItemTemplate
public partial class ListBoxContainer : System.Web.UI.UserControl
{
//declare the event using EventHandler<T>
public event EventHandler<EventArgs> ListBox_SelectedIndexChanged;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void LstFromControl_SelectedIndexChanged(object sender, EventArgs e)
{
//fire event: the check for null sees if the delegate is subscribed to
if (ListBox_SelectedIndexChanged != null)
{
ListBox_SelectedIndexChanged(sender, e);
}
}
}
Note that this above control uses the listbox change event internally, then fires an event of its own: ListBox_SelectedIndexChanged. You could create custom event args here as well, but this uses the standard EventArgs.
Your repeater which has the control may look like this
<asp:Repeater ID="rptTest" runat="server">
<ItemTemplate>
<br />
<ctrl:wucListBox ID="listBoxControl" runat="server" OnListBox_SelectedIndexChanged="ListBoxControl_SelectedIndexChanged" />
</ItemTemplate>
</asp:Repeater>
Register the control at the top of the page the repeater is on, for example
<%# Register Src="~/Common/ListBoxContainer.ascx" TagName="wucListBox" TagPrefix="ctrl" %>
It handles the event ListBox_SelectedIndexChanged, and the method which handles this is in the code behind of the page the repeater sits on.
protected void ListBoxControl_SelectedIndexChanged(object sender, EventArgs e)
{
//some code
}

Categories