How to find all controls in Gridview? - c#

I have a gridview which contains controls like checkbox dropdownlist textbox etc.. These controls are in TemplateField and some are in updatepanel in gridview. There is a EditTemplateField which has some controls and a button. When grid is in edit mode, Now I have to find all controls in this EditTemplateField in button click event. I know that this can be done using foreach loop but don't know how?

You can use the grid EditIndex to find the row that contains the controls that are in edit mode. From there you can get the control using the control ID.
TextBox txtItem = (TextBox)Grid1.Rows[Grid1.EditIndex].FindControl("txtItem");
To find all controls then try this:
foreach(Control c in Grid1.Rows[Grid1.EditIndex].Controls)
{
// do stuff in here.
}
If you have container controls in the row, and need to find things inside of them, then you need do do something to recurse down into their controls.
I don't understand though why you would need to loop though the controls, usually the controls in the edit template will be fixed, and you know what they are so accessing them directly with Findcontrol is the way to go.

If you mean in code you can do it like this:
foreach ( GridViewRow row in MyGridView.Rows )
{
TextBox myTextBox = (TextBox)row.FindControl("myTextBox");
}

Here's a nifty utility method. It's recursive so it will find nested stuff e.g.
var listOfControls = Utility.FindControlsOfType<TextBox>(yourGridRow);
If you don't know the exact type of the nested controls, use FindControlsOfType<WebControl> instead.
public static class Utility
{
public static List<T> FindControlsOfType<T>(Control ctlRoot)
{
List<T> controlsFound = new List<T>();
if (typeof(T).IsInstanceOfType(ctlRoot))
controlsFound.Add((T)(object)ctlRoot);
foreach (Control ctlTemp in ctlRoot.Controls)
{
controlsFound.AddRange(FindControlsOfType<T>(ctlTemp));
}
return controlsFound;
}
}

Take the generated html using Firebug and using http://jsfiddle.net you can include jquery and play with the html.
Add the event handler to the edit button like
For example
function edit(this)
{
var textboxID = $(this).parent().find("[id$='textBoxId']");
}

Related

Working with ListBox elements in a user control

I have a user control (ucMarket) which contains (for the purpose of simplicity) two controls: a ListBox (ucListBox) and a Label (ucLabel). I need to create multiple instances of that user control on the page dynamically (depending on the results from a DataSet), and I add them using a foreach statement and the following:
Panel1.Controls.Add(ucMarket1);
But how do I get access to the ListBox properties like Rows ? The only thing I have found so far is to cast the control as a ListBox:
ListBox listBox1 = (ListBox)ucMarket1.FindControl("ucListBox");
listBox1.Rows = 10;
For the Label part, I guess I can also do something similar:
label1 = (Label)ucMarket1.FindControl("ucLabel");
But then, how do I put that information back into the user control ? Is there a way to work directly with the user control instead of casting ?
Ok a couple of things. from a naming convention point of view, don't call the label & listbox, ucSOMETHING. This is very confusing and not clear from your example whether you're referring to the asp:Label control or some custom userControl you've written. As for accessing your controls.
I'm assuming you are creating and adding a bunch of user controls in the following manner.
for(int i = 0; i < 5; i++)
{
var control = Page.LoadControl("~/Path/To/ucMarket.ascx");
control.Id = "ucMarket" + i;
Panel1.Controls.Add(control);
}
So your best bet is to expose the Listbox on your Control as a public property.
public class ucMarket : UserControl
{
public ListBox TheListBox
{
get { return ucListBox; }
}
}
That way you could access your listbox in the following way.
var ctrl = Panel1.FindControl("ucMarket1") as ucMarket;
ctrl.TheListBox.Rows ;

FrozenGridView in update panel is not accessable

I have a RealWorld.Grids.FrozenGridView and after selecting several checkboxes (in the last column) on the grid I try to access the rows in the C# file to run some tasks on the selected rows, but the grid comes up as null, and when I try to findcontrol from the page based on the name of the grid the result is null.
gridname = (RealWorld.Grids.FrozenGridView)this.FindControl("gridname") as RealWorld.Grids.FrozenGridView;
the grid is located in an updatepanel so to access the grid I include the update panel in the find control as such:
UpdatePanel up1 = new UpdatePanel();
up1.ID = "updatepanelID";
Label gn = (Label)up1.FindControl("labelname");
I also tried:
label lbl = (Label)this.Page.FindControl("updatepanelid").FindControl("labelname") as Label;
this should happen in a button_click event
Does anyone have any experience with this type of issue?
Any help is appreciated!
The FindControl doesn't always work as expected. Try this recursive function and use your line of code that you have up top.
public static Control FindControlRecursive(Control ctlRoot, string sControlId)
{
// if this control is the one we are looking for, break from the recursion
// and return the control.
if (ctlRoot.ID == sControlId)
{
return ctlRoot;
}
// loop the child controls of this parent control and call recursively.
foreach (Control ctl in ctlRoot.Controls)
{
Control ctlFound = FindControlRecursive(ctl, sControlId);
// if we found the control, return it.
if (ctlFound != null)
{
return ctlFound;
}
}// we never found the control so just return null.
return null;
}
Your call would look something like this.
var ridname = (RealWorld.Grids.FrozenGridView)FindControl(this, "gridname") as RealWorld.Grids.FrozenGridView;

How to implement GetEnumerator method in update panel?

I want to iterate through various controls of update panel. While iterating using ID for control I want to delete some of the controls.
But I don't know how to iterate through controls of update panel using GetEnumerator method?
If we can do iteration by some other way, please let me know.
Couldn't you loop over the Controls collection of the updatepanel:
foreach(var control in myUpdatePanel.Controls) {
...
}
You can loop the ControlCollection.
Just remember that these controls can be nested, if they are in panels eg.
private void RecusiceControls(ControlCollection controls)
{
foreach (Control control in controls)
{
RecusiceControls((ControlCollection)control.Controls);
if (control is Button) // whatever the control is you are looking for
{
}
}
}

How to access a dynamically created text box in C# whose name is available in string?

I have a dynamically created (runtime creation) textbox whose name is available as a string.What i want to do is access this textbox like we do as normal textboxes .Can any one tell me how to cast it as textbox or any other solution
If you know the name of the textbox and its parent controls, you can do like this:
TextBox tb = (TextBox )parent.Controls["name"];
In addition to Iordan's answer, if you don't know exactly where on your form the textbox is, then this extension method should help alot. Note, Form's inherit from Control somewhere down the track too, so you can call it from that, or any control on your form.
public static class ExtensionMethods
{
public static Control FindControl(this Control root, string name)
{
foreach (Control c in root.Controls)
{
// Check this control
if (c.Name == name) return c;
// Check this controls subcontrols
Control tmp = c.FindControl(name);
if (tmp != null) return tmp;
}
return null;
}
}
If this still isn't flexible enough for you, then you can iterate over System.Windows.Forms.Application.OpenForms
Since you seem to have control over the creation process, put a reference to it in a dictionary.
TextBox txt = DynamicCreate(name);
map[name] = txt;
this.Controls.Add(txt);
All you have to do is look it up in your dictionary, instead of loop through all the controls on the form.
TextBox txt = map["name"];

How to Dynamically get All controls (and it's IDs) in an aspx Page?

HEllo, I need to dynamically activate fields in a page according to the service that is going to be executed...
Let me explain:
There's a page with all the possible fields and a ListBox with all the selected services to be executed, then when the user selects which service to execute (change a car plate, for example), then I need to activate only the field(s) that the service require... (The realationship between Services and Fields are stored in a database).
public void CheckAll(int pService_Id, Control pPage)
{
foreach (Control control in pPage.Controls)
{
busExecutaServico vExecuta = new busExecutaServico();
if (vExecuta.EnableField(control.ID.ToString(), Convert.ToInt32(listBoxServices.SelectedValue)))
{
switch (control.GetType().ToString())
{
case "TextBox":
TextBox controleText = (TextBox)Page.FindControl(control.ID.ToString());
controleText.Enabled = true;
break;
Note that busExecutaServico is the class which contains the method (EnableField) for checking if the selected item matches any field on the database..
I can't seem to get the control.ID.ToString() to work properly (the ID always comes as NULL)
If anyone can help me solve this, or if there's another way (even if it's completely different from what i'm trying), it would be of great help. thanks
I like to use a recursive function for locating controls by either type or ID.
public Control FindControlRecursive(Control rootControl, string controlId)
{
if (rootControl.ID == controlId)
return rootControl;
foreach (Control control in rootControl.Controls)
{
Control foundControl = FindControlRecursive(control, controlId);
if (foundControl != null)
{
return foundControl;
}
}
return null;
}
public Control FindControlRecursive(Control rootControl, Type type)
{
if (rootControl.GetType().Equals(type))
return rootControl;
foreach (Control control in rootControl.Controls)
{
Control foundControl = FindControlRecursive(control, type);
if (foundControl != null)
{
return foundControl;
}
}
return null;
}
You can adapt these to first return a collection of controls, then process them later. Might be easier to keep track of what's happening.
I learned this technique here: http://www.west-wind.com/Weblog/posts/5127.aspx
Be aware that FindControl only searches the current naming container so Page.FindControl will only find controls that are added directly to Page. For example, if you had a repeater control that had the controls you were looking for and it was added to Page, you could find your repeater control via Page.FindControl but it wouldn't find child controls within your repeater, you'd have to recursively perform the FindControl on all container controls in the page.
This might seem a bit strange but it allows you to have controls with the same ID existing on the same page. For example, if you had 10 instances of a user control with textboxes within them called "MyName", you'd really want them to not being over-writing each other's 'MyName' fields!
Your code will come across a null for an ID unless every control has been given an ID.
Also why use:-
TextBox controleText = (TextBox)Page.FindControl(control.ID.ToString());
at all instead of:-
TextBox controleText = (TextBox)control;
and indeed since you only want to change the Enabled property consider:-
((WebControl)control).Enabled = False;
That I suspect will eliminate many case statements.
In your code you don't need to search any control - you already have it in 'control' variable. You even don't need to cast it to TextBox, just to a WebControl, just do this:
...
if (vExecuta.EnableField(control.ID.ToString(), Convert.ToInt32(listBoxServices.SelectedValue)))
((WebControl)control).Enabled = true;
P.S. control.ID is already string, so you should remove any ID.ToString() also.

Categories

Resources