Get reference of image button click event in gridview in http module - asp.net

How do we pass the Click event of ImageButton inside a GridView to httpmodule
for linkbutton's i am doing this way:
if (request.Form.GetValues("__EVENTTARGET") != null)
{
//If it's a link button execute we can directley check for the params
if (request.Params.Get("__EVENTTARGET").Contains("xyz"))
{
//some Code
}
This is not working for ImageButton.

If you're trying to attach an event to a button within a gridview might I suggest in your base page on the prerender event parse through all gridviews on the page (use a recursive findcontrol algorithm) and look for any imagebuttons, if you find one you should then be able to attach an event to it.
EDIT:
I use something similar in the following:
public abstract class AmendmentPopUpWindow : BaseMasterPlanPage
{
// override this method if the correct save controls arent being hidden in the popups
public virtual IEnumerable<WebControl> SaveControls
{
get { return Controls.All().OfType<WebControl>().Where(c => c.ID.ToLower().Contains("save")); }
}
protected override void OnPreRender(EventArgs e)
{
if (WebConfiguration.Global_EnableAmendments && SystemVersion.HasValue)
{
foreach (var control in Controls.All())
{
if (control is RadioButton || control is TextBox || control is DropDownList || control is RadComboBox || control is CheckBox || control is CheckBoxList ||
control is RadEditor || control is RadTextBox || control is RadNumericTextBox)
{
var webControl = control as WebControl;
webControl.Enabled = false;
webControl.ForeColor = Color.Gray;
}
}
foreach (var saveControl in SaveControls)
saveControl.Visible = false;
}
base.OnPreRender(e);
}
EDIT: The .All() is an extension method defined as follows (stolen from here)
public static IEnumerable<Control> All(this ControlCollection controls)
{
foreach (Control control in controls)
{
foreach (Control grandChild in control.Controls.All())
yield return grandChild;
yield return control;
}
}

ImageButtons have an additional quasi-property in their names which identifies the mouse-coordinates (X and Y).
So to find the ImageButton's name your should iterate through posted parameters and found those which end with .x or .y:
foreach (string item in request.Form)
{
if (item.EndsWith(".x") || item.EndsWith(".y"))
{
var controlName = item.Substring(0, item.Length - 2);
// some code here
}
}
You could also cound this answer useful. It contains a more generic method to determine which control caused a postback.

Related

How to find control image button inside repeater, which is already inside a datalist

How to find control (i.e image button) inside repeater, that repeater is already in a datalist? because I have to perform delete operation on that image button.
Here is my code, here I'm getting repeater but not image button:
foreach (DataListItem item in Dlist_SearchResult.Controls)
{
rptrResult = (Repeater)item.FindControl("Rptr_result");
imgbtnDelete = (ImageButton)item.FindControl("imgbtnDelete");
}
You can use Recursion in your FindControl. FindControl by default is not recursive.
Try this:
private static Control FindControlRecursive(Control rootCtrl, string ID)
{
if (rootCtrl.ID == ID)
return rootCtrl;
foreach (Control ctr in rootCtrl.Controls)
{
Control foundCtl = FindControlRecursive(ctr, ID);
if (foundCtl != null)
return foundCtl;
}
return null;
}
you can call it
Button btn = FindControlRecursive((Control)Page,"imgbtnDelete");

Iterate though all controls on asp.net page

I'm using ascx and I need to iterate through all of the controls and selects each that have cssClass attribute set to 'required'.
I have the following code:
foreach (Control masterControl in Page.Controls)
{
if (masterControl is MasterPage)
{
foreach (Control formControl in masterControl.Controls)
{
if (formControl is System.Web.UI.HtmlControls.HtmlForm)
{
foreach (Control contentControl in formControl.Controls)
{
if (contentControl is ContentPlaceHolder)
{
foreach (Control childControl in contentControl.Controls)
{
}
}
}
}
}
}
}
however.. i cannot access childControl.CssClass. How do I access it?
Thanks in advance!
CssClass property is a member of the WebControl class.
You have to check if the control is a webcontrol, or, if it's only a control, you can get the attribute "class" in the attributes collection.
for example, you can do :
List<WebControl> wcs = new List<WebControl>();
GetControlList<WebControl>(Page.Controls, wcs)
foreach (WebControl childControl in wcs)
{
if(childControl.CssClass == "required") {
// process the control
}
}
You also have to iterate recursively. Code found here : Using C# to recursively get a collection of controls from a controlcollection :
private void GetControlList<T>(ControlCollection controlCollection, List<T> resultCollection)
where T : Control
{
foreach (Control control in controlCollection)
{
//if (control.GetType() == typeof(T))
if (control is T) // This is cleaner
resultCollection.Add((T)control);
if (control.HasControls())
GetControlList(control.Controls, resultCollection);
}
}
The Control class doesn't have that CssClass property, the WebControl does. So try to cast your childControl to WebControl. If that worked, then you can access the CssClass property.
WebControl webCtrl = childControl as WebControl;
if (webCtrl != null)
{
webCtrl.CssClass = "test";
}
Regarding your comment on the answer above, you need to first check that it is a WebControl and then cast it to a WebControl
var webControl = childControl as WebControl;
if(webControl != null)
{
if(webControl.CssClass == 'required')
// Do your stuff
}

ASP.Net Custom Control Render error

I am trying to create a custom control and the render method is shown below.
I get an "Object reference not set to an instance of an object" error on the bulletList.RenderControl(Writer); line.
Any ideas?
protected override void Render(HtmlTextWriter Writer)
{
if (TermSetList != null && TermSetList.Count > 0)
{
BulletedList bulletList = new BulletedList();
bulletList.Click += new BulletedListEventHandler(BulletListItem_Click);
bulletList.DisplayMode = BulletedListDisplayMode.LinkButton;
bulletList.CssClass = "tabs";
foreach (KeyValuePair<String, String> item in TermSetList)
{
ListItem listItem = new ListItem();
listItem.Text = item.Key;
listItem.Value = item.Value;
bulletList.Items.Add(listItem);
}
if (!this.Page.IsPostBack)
{
bulletList.Items[0].Selected = true;
}
bulletList.RenderControl(Writer);
base.Render(Writer);
}
}
You generally do not want to add controls during render. How your currently doing this will ensure that your click handler never gets called.
My guess as to why you are getting the error is that the control has not been added to the controls collection.
My suggestion is to move the logic to an earlier event, perhaps onload, you would not need to override the Render method then.

How to clear all form fields from code-behind?

HTML has an input button type to reset all fields in a form to their initial state in one step: <input type="reset" ... />.
Is there a similar simple way to reset all form fields of an aspx page from code-behind? Or is it necessary to reset all controls one by one with TextBox1.Text=string.Empty, TextBox2.Text=string.Empty, etc. ?
Thanks in advance!
Update:
Context is a simple Contact/"Send us a message" page with 8 asp:TextBoxes on the page (where the user enters the name, address, phone, email, message, etc.). Then he clicks on submit, the Onclick message handler in code-behind sends an email to some administrator, and all the form fields the user filled in should be emptied and he gets a notification in a label ("Message sent blabla..."). I want to have the form fields cleared to avoid that the user clicks again on submit and the same message is sent a second time.
You need only write a fork for each type of control unless one of the control has something special that needs to be done to reset it.
foreach( var control in this.Controls )
{
var textbox = control as TextBox;
if (textbox != null)
textbox.Text = string.Empty;
var dropDownList = control as DropDownList;
if (dropDownList != null)
dropDownList.SelectedIndex = 0;
...
}
ADDITION You asked how to clear controls even ones that are buried. To do that, you should create a recursive routine like so:
private void ClearControl( Control control )
{
var textbox = control as TextBox;
if (textbox != null)
textbox.Text = string.Empty;
var dropDownList = control as DropDownList;
if (dropDownList != null)
dropDownList.SelectedIndex = 0;
...
foreach( Control childControl in control.Controls )
{
ClearControl( childControl );
}
}
So, you would call this by passing the page:
ClearControls( this );
Refer this link for more information
http://www.freshcodehub.com/Article/3/clear-all-fields-like-textbox-dropdownlist-checkbox-radiobutton-label-after-form-submission-in-aspnet-c
public void ClearControls(Control parent)
{
foreach (Control c in parent.Controls)
{
if ((c.GetType() == typeof(TextBox))) //Clear TextBox
{
((TextBox)(c)).Text = "";
}
if ((c.GetType() == typeof(DropDownList))) //Clear DropDownList
{
((DropDownList)(c)).ClearSelection();
}
if ((c.GetType() == typeof(CheckBox))) //Clear CheckBox
{
((CheckBox)(c)).Checked = false;
}
if ((c.GetType() == typeof(CheckBoxList))) //Clear CheckBoxList
{
((CheckBoxList)(c)).ClearSelection();
}
if ((c.GetType() == typeof(RadioButton))) //Clear RadioButton
{
((RadioButton)(c)).Checked = false;
}
if ((c.GetType() == typeof(RadioButtonList))) //Clear RadioButtonList
{
((RadioButtonList)(c)).ClearSelection();
}
if ((c.GetType() == typeof(HiddenField))) //Clear HiddenField
{
((HiddenField)(c)).Value = "";
}
if ((c.GetType() == typeof(Label))) //Clear Label
{
((Label)(c)).Text = "";
}
if (c.HasControls())
{
ClearControls(c);
}
}
}
using the manual approach of String.Empty for each and every Textbox or any other field will be cumbersome, also by using Response.Redirect(); it will be difficult to show any confirmation message or same. So, on reading so many blogs i have found a reliable approach so far:
Public void reset(Control control)
{
foreach (Control x in control.Controls)
{
if (x is TextBox)
{
(x as TextBox).Text = String.Empty;
}
else if (x is DropDownList)
{
(x as DropDownList).SelectedIndex = 0;
}
.
.
reset(x);
}
}
use this code as reset(this); in your page wherever you want to reset or clear the values. At end of the if conditions do not forget to use the function recursively using the same
`Control` object x.
Using form.Controls.Clear() is not such a good approach because it will clear the entire form and you will even lose all the buttons on the form.
Instead if you just want to clear all the form fields like text fields and radio buttons I would recommend you try the following:
If you have a Reset button “Button1” then on click call a function reset();
In the reset function:
protected void resetButton_Click(object sender, EventArgs e)
{
TextBox1.Text=""; //set equal to empty string to all fields
}
Or redirect to same page by terminating the previous page
protected void resetButton_Click(object sender, EventArgs e)
{
Response.Redirect("~/Test2.aspx", true);
}
For your scenario the easiest way to clear the fields, in my opinion, is to turn off the ViewState (EnableViewState=false) of the controls you want to appear blank after the submit.
Or perhaps for the whole page unless there is some state you need.

Programatic Access to DragHandleTemplate in ASP.NET AJAX ReorderList

Is there a way to programatically access the DragHandleTemplate of a ReorderList (ASP.NET AJAX Control Toolkit) ... Specifically during ItemDataBound for the ReorderList, in order to change its appearance at the per item level?
You can also express FindControlRecursive in LINQ:
private Control FindControlRecursive(Control root, string id)
{
return root.ID == id
? root
: (root.Controls.Cast<Control>().Select(c => FindControlRecursive(c, id)))
.FirstOrDefault(t => t != null);
}
Unfortunately there is no way of getting drag holder from ReorderListItem. Instead, you can create a server control inside DragHandleTemplate (e.g. PlaceHolder) and then find it in your ItemDataBound event handler:
In aspx file:
<DragHandleTemplate>
<div class="dragHandle">
<asp:Label ID="lblDragHandle" runat="server" />
</div>
</DragHandleTemplate>
In aspx.cs file:
protected void ReorderList1_ItemDataBound(object sender, AjaxControlToolkit.ReorderListItemEventArgs e)
{
Label lblDragHandle = (Label)FindControlRecursive(e.Item, "lblDragHandle");
lblDragHandle.Text = e.Item.ItemIndex.ToString();
}
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;
}
I copied FindControlRecursive method from Jeff's blog.
You can not access DragHandleTemplate programatically on the server, but if you create the surrounding elements with unique ID's (per row) you should be able the use CSS-selectors or Javascript to only change some of the items.

Resources