unable to capture ImageButton click in postback event - asp.net

Unable to capture the Imagebuttonclick event in postback.
I am using the below code for Button click and tried for Imagebutton as well however "Button" click its working and not for Image button.
public Control GetPostBackControl(Page page)
{
Control control = null;
string ctrlname = page.Request.Params.Get("__EVENTTARGET");
if ((ctrlname != null) & ctrlname != string.Empty)
{
control = page.FindControl(ctrlname);
}
else
{
foreach (string ctl in page.Request.Form)
{
Control c = page.FindControl(ctl);
if (c is System.Web.UI.WebControls.Button)
{
control = c;
break;
}
}
}
return control;
}
Any solution?

try using replacing your button check block with this:
if (c is System.Web.UI.WebControls.ImageButton)
{
control = c;
break;
}

Got the solution:
Added one more check in the above mentioned code,
// handle the ImageButton postbacks
if (control == null)
{
for (int i = 0; i < page.Request.Form.Count; i++)
{
if ((page.Request.Form.Keys[i].EndsWith(".x")) || (page.Request.Form.Keys[i].EndsWith(".y")))
{
control = page.FindControl(page.Request.Form.Keys[i].Substring(0, page.Request.Form.Keys[i].Length - 2));
}
}
}
And now I am able to capture the ImageButton postback event.
Thanks

Related

Why ViewState and Control Values lost on partial Postback using AJAXFileUpload?

I have a .aspx page containing button which opens the popup on button click.
The popup window have AJAXFileUpload control. When button is clicked to open the popup, session values are sent to popup and on page load these session values are assigned to ViewState and HiddenField, DataTable.
Problem:
When i click on Upload button in popup containing AjaxFileUploadit saves the images to the table in AJAXUploadComplete event. In this event i am not able to access the ViewState,HiddenField and DataTable Values dont know why?
Popup.aspx.cs
DataTable dt=new DataTable();
protected void Page_Load(object sender, EventArgs e)
{
int noOfImages;
string[] imagePaths;
if (dt != null && dt.Rows.Count==0)
{
dt.Columns.Add("QuoteID");
dt.Columns.Add("PrepID");
dt.Columns.Add("IsPrep");
dt.Rows.Add(string.Empty, string.Empty, string.Empty);
}
if ((!IsPostBack ))
{
if (Session["IsPrep"] != null || ViewState["IsPrep"]!= null)
{
int Isprep = Convert.ToInt32(Session["IsPrep"].ToString());
if (Session["IsPrep"] != null)
{
ViewState["IsPrep"] = Session["IsPrep"];
ViewState["QuoteID"] = Convert.ToString(Session["QuoteIDForListing"]);
int intQuoteID = Convert.ToInt32(ViewState["QuoteID"]);
hdnQuoteID.Value = intQuoteID.ToString();
ViewState["PrepID"] = Convert.ToString(Session["PrepIDForListing"]);
if (dt != null && dt.Rows.Count > 0)
{
dt.Rows[0]["QuoteID"] = Convert.ToString(Session["QuoteIDForListing"]);
dt.Rows[0]["PrepID"] = Convert.ToString(Session["PrepIDForListing"]);
dt.Rows[0]["IsPrep"] = Convert.ToString(Session["IsPrep"]);
}
Session["IsPrep"] = null;
Session["QuoteIDForListing"] = null;
Session["PrepIDForListing"] = null;
}
}
}
}
protected void AjaxFileUpload1_UploadComplete1(object sender, AjaxControlToolkit.AjaxFileUploadEventArgs e)
{
//here: ViewState,HiddenField,DataTable values are all get cleared dont know why?
if (dt != null && dt.Rows.Count > 0)
{
//here dt is set to null any idea?
}
//if (!string.IsNullOrEmpty(Convert.ToString(ViewState["QuoteID"])))
if (!string.IsNullOrEmpty(Convert.ToString(hdnQuoteID.Value))&& hdnIsPrepId.Value=="0")
{
int QuoteID = Convert.ToInt32(ViewState["QuoteID"]);
///some code here
}
// else if (!string.IsNullOrEmpty(Convert.ToString(ViewState["PrepID"])))
else if (!string.IsNullOrEmpty(Convert.ToString(hdnPrepID.Value)) && hdnIsPrepId.Value == "1")
{
int PrepID = Convert.ToInt32(ViewState["PrepID"]);
///some code here
}
}
NOTE: Same functionality works fine on a page. But, used with the popup it flushed all the values of HiddenField,DataTable,ViewState.
Session cant be used to store data after popup opened because multiple instance of windows may be opened at a time.
Also, when query string is used with Popup to send values the AjaxFileUpload gives error as it appends its own querystring contextkey and guid.
Please suggest any solution/change?

How to reference a user control in its own code behind?

Let's say I have a user control with a couple of buttons. I'd like to know which one caused the postback, using this method:
public static Control GetPostBackControl(Page page)
{
Control control = null;
string ctrlname = page.Request.Params.Get("__EVENTTARGET");
if (ctrlname != null && ctrlname != string.Empty)
{
control = page.FindControl(ctrlname);
}
else
{
foreach (string ctl in page.Request.Form)
{
Control c = page.FindControl(ctl);
if (c is System.Web.UI.WebControls.Button)
{
control = c;
break;
}
}
}
return control;
}
And this is how I am calling it:
string btn = GetPostBackControl(this.Page).ID;
I'm getting the "Object reference not set to an instance of an object." I know now that the problem comes from the fact that I'm using this.Page, which represents the parent page.
How to reference the user control that I'm in? (not the parent page) So that it can work with the method to find the button that caused the postback?
Thanks for helping.
EDIT
Both buttons are located inside the user control. GetPostBackControl() is also in the code-behind of the user control.
I did a quick example on your given code and it worked out pretty fine. Perhaps you did miss checking for Page.IsPostBack? Obviously there will only be a postBackControl if there is a postBack...
#Buttons - they will be rendered as <input type="submit"> so they won't appear within ___EVENTTARGET. That's why Ryan Farlay wrote in his blog
However, you can still get to it, just in a different way. Since the
button (or input) is what causes the form to submit, it is added to
the items in the Form collection, along with all the other values from
the submitted form. [...] If you were to
look in the Form collection for anything that is a button then that
will be what caused the postback (assuming that it was a button that
caused the page to submit). If you first check the __EVENTTARGET, then
if that is blank look for a button in the Form collection then you
will find what caused the postback
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
Control postBackControl = GetPostBackControl(this.Page);
Debug.WriteLine("PostBackControl is: " + postBackControl.ID);
}
}
public static Control GetPostBackControl(Page page)
{
Control control = null;
string ctrlname = page.Request.Params.Get("__EVENTTARGET");
if (ctrlname != null && ctrlname != string.Empty)
{
control = page.FindControl(ctrlname);
}
else
{
foreach (string ctl in page.Request.Form)
{
Control c = page.FindControl(ctl);
if (c is System.Web.UI.WebControls.Button)
{
control = c;
break;
}
}
}
return control;
}

how to use updatepanel with AsyncRefresh event

I developing an asp.net web application.In that application i am using asyncRefresh event
for continuously updating the value.If i am using updatepanel the asyncRefresh event won't get the focus.Without updatepanel evet getting the focus.I want to use asynRefresh event with updatepanel.Any one Please help for this problem.
Thanks&Regards
Lijo Thomas
protected void Page_Load(object sender, EventArgs e)
{
object et = Request.Form["__EVENTTARGET"] as object;
if (et != null)
{
Control c = Page.FindControl(et.ToString());
if (c != null)
{
ScriptManager.GetCurrent(this).SetFocus(GetUniqueIdSmart(c));
}
}
}
protected static string GetUniqueIdSmart(Control control)
{
string id = control.UniqueID.Replace('$', '_');
string controlIDSuffix = "";
RadioButtonList rbl = control as RadioButtonList;
if (rbl != null)
{
controlIDSuffix = "_0";
int t = 0;
foreach (ListItem li in rbl.Items)
{
if (li.Selected)
{
controlIDSuffix = "_" + t.ToString();
break;
}
t++;
}
}
else if (control is CheckBoxList)
{
controlIDSuffix = "_0";
}
id += controlIDSuffix;
return id;
}

Saving State Dynamic UserControls...Help!

I have page with a LinkButton on it that when clicked, I'd like to add a Usercontrol to the page. I need to be able to add/remove as many controls as the user would like. The Usercontrol consists of three dropdownlists. The first dropdownlist has it's auotpostback property set to true and hooks up the OnSelectedIndexChanged event that when fired will load the remaining two dropdownlists with the appropriate values.
My problem is that no matter where I put the code in the host page, the usercontrol is not being loaded properly. I know I have to recreate the usercontrols on every postback and I've created a method that is being executed in the hosting pages OnPreInit method. I'm still getting the following error:
The control collection cannot be modified during DataBind, Init, Load, PreRender or Unload phases.
Here is my code:
Thank you!!!!
bool createAgain = false;
IList<FilterOptionsCollectionView> OptionControls
{
get
{
if (SessionManager.Current["controls"] != null)
return (IList<FilterOptionsCollectionView>)SessionManager.Current["controls"];
else
SessionManager.Current["controls"] = new List<FilterOptionsCollectionView>();
return (IList<FilterOptionsCollectionView>)SessionManager.Current["controls"];
}
set
{
SessionManager.Current["controls"] = value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
Master.Page.Title = Title;
LoadViewControls(Master.MainContent, Master.SideBar, Master.ToolBarContainer);
}
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
System.Web.UI.MasterPage m = Master;
Control control = GetPostBackControl(this);
if ((control != null && control.ClientID ==
(lbAddAndCondtion.ClientID) || createAgain))
{
createAgain = true;
CreateUserControl(control.ID);
}
}
protected void AddAndConditionClicked(object o, EventArgs e)
{
var control = LoadControl("~/Views/FilterOptionsCollectionView.ascx");
OptionControls.Add((FilterOptionsCollectionView)control);
control.ID = "options" + OptionControls.Count.ToString();
phConditions.Controls.Add(control);
}
public event EventHandler<Insight.Presenters.PageViewArg> OnLoadData;
private Control FindControlRecursive(Control root, string id)
{
if (root.ID == id)
{
return root;
}
foreach (Control c in root.Controls)
{
Control t = FindControlRecursive(c, id);
if (t != null)
{
return t;
}
}
return null;
}
protected Control GetPostBackControl(System.Web.UI.Page page)
{
Control control = null;
string ctrlname = Page.Request.Params["__EVENTTARGET"];
if (ctrlname != null && ctrlname != String.Empty)
{
control = FindControlRecursive(page, ctrlname.Split('$')[2]);
}
else
{
string ctrlStr = String.Empty;
Control c = null;
foreach (string ctl in Page.Request.Form)
{
if (ctl.EndsWith(".x") || ctl.EndsWith(".y"))
{
ctrlStr = ctl.Substring(0, ctl.Length - 2);
c = page.FindControl(ctrlStr);
}
else
{
c = page.FindControl(ctl);
}
if (c is System.Web.UI.WebControls.CheckBox ||
c is System.Web.UI.WebControls.CheckBoxList)
{
control = c;
break;
}
}
}
return control;
}
protected void CreateUserControl(string controlID)
{
try
{
if (createAgain && phConditions != null)
{
if (OptionControls.Count > 0)
{
phConditions.Controls.Clear();
foreach (var c in OptionControls)
{
phConditions.Controls.Add(c);
}
}
}
}
catch (Exception ex)
{
throw ex;
}
}
Here is the usercontrol's code:
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="FilterOptionsCollectionView.ascx.cs" Inherits="Insight.Website.Views.FilterOptionsCollectionView" %>
namespace Insight.Website.Views
{
[ViewStateModeById]
public partial class FilterOptionsCollectionView : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected override void OnInit(EventArgs e)
{
LoadColumns();
ddlColumns.SelectedIndexChanged += new RadComboBoxSelectedIndexChangedEventHandler(ColumnsSelectedIndexChanged);
base.OnInit(e);
}
protected void ColumnsSelectedIndexChanged(object o, EventArgs e)
{
LoadCriteria();
}
public void LoadColumns()
{
ddlColumns.DataSource = User.GetItemSearchProperties();
ddlColumns.DataTextField = "SearchColumn";
ddlColumns.DataValueField = "CriteriaSearchControlType";
ddlColumns.DataBind();
LoadCriteria();
}
private void LoadCriteria()
{
var controlType = User.GetItemSearchProperties()[ddlColumns.SelectedIndex].CriteriaSearchControlType;
var ops = User.GetItemSearchProperties()[ddlColumns.SelectedIndex].ValidOperators;
ddlOperators.DataSource = ops;
ddlOperators.DataTextField = "key";
ddlOperators.DataValueField = "value";
ddlOperators.DataBind();
switch (controlType)
{
case ResourceStrings.ViewFilter_ControlTypes_DDL:
criteriaDDL.Visible = true;
criteriaText.Visible = false;
var crit = User.GetItemSearchProperties()[ddlColumns.SelectedIndex].SearchCriteria;
ddlCriteria.DataSource = crit;
ddlCriteria.DataBind();
break;
case ResourceStrings.ViewFilter_ControlTypes_Text:
criteriaDDL.Visible = false;
criteriaText.Visible = true;
break;
}
}
public event EventHandler OnColumnChanged;
public ISearchCriterion FilterOptionsValues { get; set; }
}
}
I figured it out. Here is my solution:
I modified the GetPostBackControl to look for not only the linkbutton that inserts the user control, but for controls that contain the id of child controls of the inserted user control(as to capture the OnSelectedIndexChanged that gets fired from inside my user control).
protected Control GetPostBackControl(System.Web.UI.Page page)
{
Control control = null;
string ctrlname = Page.Request.Params["__EVENTTARGET"];
if (ctrlname != null && ctrlname != String.Empty)
{
//if it contains options then it's a control inside my usercontrol
if (ctrlname.Split('$')[2].Contains("options"))
{
var c = new Control();
c.ID = ctrlname;
return c;
}
else
{
control = FindControlRecursive(page, ctrlname.Split('$')[2]);
}
}
else
{
string ctrlStr = String.Empty;
Control c = null;
foreach (string ctl in Page.Request.Form)
{
if (ctl.EndsWith(".x") || ctl.EndsWith(".y"))
{
ctrlStr = ctl.Substring(0, ctl.Length - 2);
c = page.FindControl(ctrlStr);
}
else
{
c = page.FindControl(ctl);
}
if (c is System.Web.UI.WebControls.CheckBox ||
c is System.Web.UI.WebControls.CheckBoxList)
{
control = c;
break;
}
}
}
return control;
}
Then I modify the OnPreInit event to look for controls with an id of the linkbutton or an id that contains "options" :
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
System.Web.UI.MasterPage m = Master;
Control control = GetPostBackControl(this);
if (control != null)
{
if ((control.ClientID == (lbAddAndCondtion.ClientID) || createAgain) || control.ID.Contains("options"))
{
createAgain = true;
CreateUserControl(control.ID);
}
}
}
The critical fix was in the CreateUserControl method. In my original code I was trying to directly load the user control from my generic list that was stored in Session. I changed that to actually create a new instance of the user control, assign that new instance an id that matches the one stored in Session, and then add it to the placeholder:
protected void CreateUserControl(string controlID)
{
try
{
if (createAgain && phConditions != null)
{
if (OptionControls.Count > 0)
{
phConditions.Controls.Clear();
foreach (var c in OptionControls)
{
FilterOptionsCollectionView foc = new FilterOptionsCollectionView();
foc = Page.LoadControl("~/Views/FilterOptionsCollectionView.ascx") as FilterOptionsCollectionView;
foc.ID = c.ID;
phConditions.Controls.Add(foc);
}
}
}
}
catch (Exception ex)
{
throw ex;
}
}
The only thing I changed in the user control was moving the method that loads my drop down lists's and wiring up the OnSelectedIndexChanged event into the OnInit event. Now I can dynamically load as many instances of the user control I want and all of the event's inside the user control fire correctly and state is persisted across postbacks!!
Hope this helps someone else!!

How to Get Source of postback

if (Page.IsPostBack)
{
//here I need to know which control causes the postback
}
Thanks
See this posting
Get control name in Page_Load event which make the post back
Here is the code from link "marked as Answer"( Just pasting code here so that we can save readers time):
private string getPostBackControlName()
{
Control control = null;
//first we will check the "__EVENTTARGET" because if post back made by the controls
//which used "_doPostBack" function also available in Request.Form collection.
string ctrlname = Page.Request.Params["__EVENTTARGET"];
if (ctrlname != null && ctrlname != String.Empty)
{
control = Page.FindControl(ctrlname);
}
// if __EVENTTARGET is null, the control is a button type and we need to
// iterate over the form collection to find it
else
{
string ctrlStr = String.Empty;
Control c = null;
foreach (string ctl in Page.Request.Form.AllKeys)
{
c = Page.FindControl(ctl);
if (c is System.Web.UI.WebControls.Button ||
c is System.Web.UI.WebControls.ImageButton )
{
control = c;
break;
}
}
}
if (control == null)
return "";
else
return control.ID;
}

Resources