How to find GridView on Page - asp.net

I have nested GridViews on my page (Default) and I need to get the ID of the GridView inside but it's returning null. I have an UpdatePanel outside the nested GridViews. It's using a masterpage.
GridView gv = (GridView)UpdatePanel1.FindControl("GridViewSchedule");

Here is the helper method to find a control recursively.
public static Control FindControlRecursive(Control root, string id)
{
if (root.ID == id)
return root;
return root.Controls.Cast<Control>()
.Select(c => FindControlRecursive(c, id))
.FirstOrDefault(c => c != null);
}
// Usage
var gridView = FindControlRecursive(UpdatePanel1, "GridViewSchedule");

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");

Get reference of image button click event in gridview in http module

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.

How to set the .Selected property of an item in ASP.NET MVC SelectList using LINQ?

I am trying to populate a SelectList in an action method for a dropdown list in the view. The dropdown gets displayed on the view just fine but the selected attribute doesn't show up using the following code:
public ActionResult Edit(int ID)
{
var ctx = new NorthwindEntities();
var product = ctx.Products.Where(p => p.ProductID == ID).SingleOrDefault();
var selectList = new SelectList(ctx.Categories, "CategoryID", "CategoryName");
selectList.Where(s => s.Value == product.CategoryID.ToString()).SingleOrDefault().Selected = true;
ViewData["CategoryID"] = selectList;
return View(product);
}
However, passing the selectedValue parameter to SelectList constructor does the job:
var selectList = new SelectList(ctx.Categories, "CategoryID", "CategoryName", product.CategoryID.ToString());
My guess is that Either the LINQ expession is the problem or SelectedItem can only be specified in the SelectList constructor. Any ideas?
This question is answered here
Set selected value in SelectList after instantiation
If you still think it is wrong then break your linq query up and check to see if you can find an object in the list, and then do an if( obj != null) { selected = true;}
But from what I have read the selected property can only be set in the constructor.
in that link is a wrapper/helper method
public static string DropDownListEx(this HtmlHelper helper, string name, SelectList selectList, object selectedValue)
{
return helper.DropDownList(name, new SelectList(selectList.Items, selectList.DataValueField, selectList.DataTextField, selectedValue));
}
That migth help you

FindControl() method for Dynamically Nested Controls on PostBack

How do you get a specific nested control of dynamically created controls (i.e. the child of a dynamic control)? The FindControl() method does not work because it only deals with TopLevel dynamic controls I believe.
You need to recurse through your controls: (C# code)
public static Control FindControl(Control parentControl, string fieldName)
{
if (parentControl != null && parentControl.HasControls())
{
Control c = parentControl.FindControl(fieldName);
if (c != null)
{
return c;
}
// if arrived here, then not found on this level, so search deeper
// loop through collection
foreach (Control ctrl in parentControl.Controls)
{
// any child controls?
if (ctrl.HasControls())
{
// try and find there
Control c2 = FindControl(ctrl, fieldName);
if (c2 != null)
{
return c2; // found it!
}
}
}
}
return null; // found nothing (in this branch)
}
This is an extension method I've used in times past. I've found that using it as an extension method makes the code a little more expressive, but that's just preference.
/// <summary>
/// Extension method that will recursively search the control's children for a control with the given ID.
/// </summary>
/// <param name="parent">The control who's children should be searched</param>
/// <param name="controlID">The ID of the control to find</param>
/// <returns></returns>
public static Control FindControlRecursive(this Control parent, string controlID)
{
if (!String.IsNullOrEmpty(parent.ClientID) && parent.ClientID.Equals(controlID)) return parent;
System.Web.UI.Control control = null;
foreach (System.Web.UI.Control c in parent.Controls)
{
control = c.FindControlRecursive(controlID);
if (control != null)
break;
}
return control;
}

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