Iterate all controls in BindingNavigator - c#

I have some windows forms that each has some controls including buttons,ComboBox,... and also in each form i have a Bindingnavigator control that i added some new Toolstrip buttons to it, how can i write a general method that get 3 parameters and iterate all controls on a form(including that toolstrip buttons) and enable/disable Enabled status of an special control?
my method signature is like this:
Public SetStatusOf(Form frm,string controlName,bool status)

From the question, and from what I understood, you need this:
foreach (Control c in frm.Controls)
{
if (c.Name.Equals(controlName))
c.Enabled = status;
}
but you can also directly use
frm.Controls[controlName].Enabled = status;

Related

How can one refresh TabContol inner controls?

First, I read this Reset all the items in a form
It was a great help until I realised all my controls are inside a TabControl containing itself several tabs in which there are all the common controls i.e. textbox, datetimepicker, datagrigview, etc....
Then I tried MyTabControl.Controls.Clear() but this deleted all tabs in the form.
How can I implement this Reset all the items in a form in a TabControl ?
use:
foreach (Control c in GetAll(myTabControl))
{
ResetAllControls(c);
}
in which ResetAllControls is the method in your referenced link and
public static IEnumerable<Control> GetAll(Control control)
{
var controls = control.Controls.Cast<Control>();
return controls.SelectMany(ctrl => GetAll(ctrl))
.Concat(controls);
}
from the accepted answer of this question.

How to find all controls in Gridview?

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']");
}

Recursively notify child controls via C#

I have a form MainForm which is a Windows Forms form that contains many child controls. I want to call one function on MainForm that notifies all of its children. Does the Windows Forms form provide a means to do this? I played with update, refresh and invalidate with no success.
foreach (Control ctrl in this.Controls)
{
// call whatever you want on ctrl
}
If you want access to all controls on the form, and also all the controls on each control on the form (and so on, recursively), use a function like this:
public void DoSomething(Control.ControlCollection controls)
{
foreach (Control ctrl in controls)
{
// do something to ctrl
MessageBox.Show(ctrl.Name);
// recurse through all child controls
DoSomething(ctrl.Controls);
}
}
... which you call by initially passing in the form's Controls collection, like this:
DoSomething(this.Controls);
The answer from MusiGenesis is elegant, (typical in a good way), nice and clean.
But just to offer an alternative using lambda expressions and an 'Action' for a different type of recursion:
Action<Control> traverse = null;
//in a function:
traverse = (ctrl) =>
{
ctrl.Enabled = false; //or whatever action you're performing
traverse = (ctrl2) => ctrl.Controls.GetEnumerator();
};
//kick off the recursion:
traverse(rootControl);
No, there isn't. You must roll out your own.
On a side note - WPF has "routed events" which is exactly this and more.
You are going to need a recursive method to do this (as below), because controls can have children.
void NotifyChildren( control parent )
{
if ( parent == null ) return;
parent.notify();
foreach( control child in parent.children )
{
NotifyChildren( child );
}
}

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