change property of rad controls in form - c#

How can I access a property of rad controls in my form. something like code bellow
foreach (Control ctrl in this.Controls)
{
RadControl rc = ctrl as RadControl;
if (rc != null)
{
if (rc.GetType() == typeof(Telerik.WinControls.UI.RadButton))
{
rc.Image = ....
}
}
}
thanks

In your conditional statement you want to test if (ctrl is RadControl)
And you want to make this into a recursive function that will go down through all Control collections in the page.
private void DoSomethingToRadControls(ControlCollection controls) {
if (controls != null && controls.Any()) {
foreach (Control ctrl in controls) {
if (ctrl is RadControl) {
// do something
}
DoSomethingToRadControls(ctrl.Controls);
}
}
}

Related

How can i create a method type bool and loop over controls to decide on cases?

private bool LoopOverControls(bool reset, bool checkIfEmpty)
{
bool results;
foreach (Control ctrl in this.Controls)
{
if ((ctrl as TextBox) != null)
{
if (reset == true)
(ctrl as TextBox).Text = "";
if (checkIfEmpty == true)
results = true;
}
}
return results;
}
I want to use the method in some places in the code. Instead making loop over the controls over again each time i want to make a method i can call.
The method was before:
private void LoopOvercontrols(bool reset, bool checkIfEmpty)
{
foreach (Control ctrl in this.Controls)
{
if ((ctrl as TextBox) != null)
{
if (reset == true)
(ctrl as TextBox).Text = "";
if (checkIfEmpty == true)
}
}
}
And this is the places i'm using the loop over the controls in my code the first place is in the constructor: I check if the textBoxes are not empty then do something in this case change btnReset enable true.
foreach (Control ctrl in this.Controls)
{
if ((ctrl as TextBox) != null)
{
(ctrl as TextBox).TextChanged += on_TextChanged;
if ((ctrl as TextBox).Text != "")
{
btnReset.Enabled = true;
}
}
}
Then inside another event this time i check if the textboxes are empty and set the btnReset enable to false:
foreach (Control ctrl in this.Controls)
{
if ((ctrl as TextBox) != null)
{
(ctrl as TextBox).TextChanged += on_TextChanged;
if ((ctrl as TextBox).Text == "")
{
btnReset.Enabled = false;
}
}
}
So far i'm looping over the textBoxes in two places but i might want to loop over them again later in other places. The problem is how to make the method LoopOverControls so i can decide with a bool and maybe other properties some cases and using buttons or other controls within the decitions ?
You can write a method that receive the action to be executed as parameter.
The work for this new method is to enumerate all the textboxes and call the action method for each one.
public void TextBoxEnumerateAndAction(Action<TextBox> execute)
{
// Get just the TextBoxes, no need of ugly casts...
foreach(TextBox t in this.Controls.OfType<TextBox>())
{
execute?.Invoke(t);
// This part is common to every textbox, so it can stay inside the
// enumeration loop....
btnReset.Enabled = !string.IsNullOrEmpty(t.Text)
}
}
Now define the Action methods to pass to TextBoxEnumerateAndAction
void AddTextChangedHandler(TextBox t)
{
t.TextChanged += on_TextChanged;
}
void RemoveTextChangedHandler(TextBox t)
{
t.TextChanged -= on_TextChanged;
}
So, everywhere you need to add or remove the TextChanged handler you could call
TextBoxEnumerateAndAction(AddTextChangedHandler);
Or if you have more fancy situations, you could simply define another action to pass to TextBoxEnumerateAndAction
I suggest you just add some comfort methods to contain the looping and type selection logic and allow callers to pass in delegate function to control the applied logic.
for example:
public void ActOn<TControl>(Action<TControl> applyFunction)
where TControl : Control
{
if (applyFunction == null) { throw new ArgumentNullException(nameof(applyFunction)); }
var controlsOfChosenType = this
.Controls
.OfType<TControl>();
foreach (var control in controlsOfChosenType)
{
applyFunction(control);
}
}
Then you can use it like this:
ActOn<TextBox>(textbox => textbox.Text = DateTime.Now.ToString());

radiobuttons - test if checked - why do first 2 approaches fail?

I was wondering why below did not work as expected...
if if-statement changed to (!ctrl.checked) it returns all radio-button's names)
myForm f = new myForm();
foreach (RadioButton ctrl in f.Controls.OfType<RadioButton>())
{
if (ctrl.Checked)
MessageBox.Show(ctrl.Name);
}
I also tried
foreach (Control c in f.controls)
if (c is radiobutton)
{
if (c.Checked)
{
messagebox.show(c.name);
}
when I then put all radio-buttons in a group-box and used below code:
foreach (RadioButton c in groupBox1.Controls)
{
if (c.Checked)
{
MessageBox.Show(c.Name);
}
}
it worked fine.
what's the difference here.
any help appreciated
I'm guessing that your radio button is the child of a control other than the form. You need to recursively search for the radio buttons.
public void DisplayRadioButtons()
{
Form f = new Form();
RecursivelyFindRadioButtons(f);
}
private static void RecursivelyFindRadioButtons(Control control)
{
foreach (Control childControl in control.Controls)
{
RecursivelyFindRadioButtons(childControl);
if (childControl is RadioButton && ((RadioButton) childControl).Checked)
{
MessageBox.Show(childControl.Name);
}
}
}

Get the list of Child controls inside a groupbox

I have a groupbox in my application which contains child controls.(As seen in the attchached pic). I want to enumerate through all the textboxes for performing some validation using a simple foreach loop.
This document outline would give a fair idea of the housing of the controls
foreach (Control control in grpBxTargetSensitivity.Controls)
{
if (control is FlowLayoutPanel && control.HasChildren)
{
foreach (Control ctrl in control.Controls)
{
if (ctrl is Panel && ctrl.HasChildren)
{
foreach (Control tbox in ctrl.Controls)
{
if (tbox is TextBox)
{
TextBox textbox = tbox as TextBox;
validData &= !string.IsNullOrWhiteSpace(textbox.Text);
}
}
}
}
}
}
My question is, Is there a better way (possibly through LINQ) to get all the controls including the textboxes housed inside the panels than the above method.?
I don't know that this is any better.. whether it's easier to read is a matter of opinion:
var validData
= grpBxTargetSensitivity.Controls.OfType<FlowLayoutPanel>()
.SelectMany(c => c.Controls.OfType<Panel>())
.SelectMany(c => c.Controls.OfType<TextBox>())
.All(textbox => !string.IsNullOrWhiteSpace(textbox.Text));
This'll grab all TextBoxes inside of all Panels in all FlowLayoutPanels in your GroupBox, and return true if all of those TextBoxes have a value in them.
A one liner slution,
IEnumerable<TextBox> collection = grpBxTargetSensitivity.Children.OfType<TextBox>(); //assuming you are looking for TextBox
or
You can try following generic method,
public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
{
if (depObj != null)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
if (child != null && child is T)
{
yield return (T)child;
}
foreach (T childOfChild in FindVisualChildren<T>(child))
{
yield return childOfChild;
}
}
}
}
then enumerate over the controls as follows,
foreach (TextBox tb in FindVisualChildren<TextBox>(grpBxTargetSensitivity)) //assuming you are looking for TextBox
{
// do something
}
I create one method by the ability to find any controls (or T type) and any inherited object from Control (or T type) for you:
public static List<T> GetSubControlsOf<T>(Control parent) where T : Control
{
var myCtrls = new List<T>();
foreach (Control ctrl in parent.Controls)
{
// if ctrl is type of T
if (ctrl.GetType() == typeof(T) ||
ctrl.GetType().IsInstanceOfType(typeof(T)))
{
myCtrls.Add(ctrl as T);
}
else if (ctrl.HasChildren)
{
var childs = GetSubControlsOf<T>(ctrl);
if (childs.Any())
myCtrls.AddRange(childs);
}
}
return myCtrls;
}
and use that this form for e.g:
foreach (var textbox in GetSubControlsOf<TextBox>(this))
{
validData &= !string.IsNullOrWhiteSpace(textbox.Text);
}
I found following links on StackOverflow itself:
How to get ALL child controls of a Windows Forms form of a specific type (Button/Textbox)?
Loop through all the user controls on a page
Give them try. Should work in your case.

Why would I get an "Invalid Cast" with this code?

I have a form which contains the following types of controls (only):
Button
ComboBox
Label
TextBox
I have a "Clear" button that calls this method:
private void ClearControls()
{
foreach (TextBox txtbx in this.Controls)
{
if (txtbx != null)
{
txtbx.Text = string.Empty;
}
}
foreach (ComboBox cmbx in this.Controls)
{
if (cmbx != null)
{
cmbx.SelectedIndex = -1;
}
}
}
...yet when I call it, the app hangs, and the log file says "Invalid cast" for that method. How could that be? It should deal with the TextBoxes and ComboBoxes, and disregard the rest - where could the invalid cast be?
That's not what foreach does.
Specifying a type in a foreach loop does not skip items of other types; instead, it will cast every item to that type.
You can call .OfType<T>() to get the filtered list that you're looking for.
The foreach will try to cast the control to the specified type which will give that invalid cast exception, what you should do is:
foreach(Control ctrl in this.Controls)
{
if(ctrl as TextBox != null)
{
//Textbox logic
}
if(ctrl as ComboBox!= null)
{
//ComboBox logic
}
}
Based on Gunther's starting point, this works:
foreach (Control ctrl in this.Controls)
{
if (ctrl as TextBox != null)
{
ctrl.Text = string.Empty;
}
if (ctrl as ComboBox != null)
{
((ComboBox)ctrl).SelectedIndex = -1;
}
}

Clear all controls in a ASP.NET page with a Master page

I have a asp.net page which is inherited from a master page .I want to clear all controls in this page .I tried using the bellow method .This is not working if a master page is there. Otherwise its working fine any ideas?
private void ClearControls()
{
foreach(Control c in Page.Controls)
{
foreach (Control ctrl in c.Controls)
{
if (ctrl is TextBox)
{
((TextBox)ctrl).Text = string.Empty;
}
}
}
}
try this:
public void FindAllTextBox(Control ctrl)
{
if (ctrl != null)
{
foreach (Control c in ctrl.Controls)
{
if (c is TextBox)
((TextBox)c).Text = string.empty;
FindAllTextBox(c);
}
}
}
Ex.:
Control ctrl = this.FindControl("content");
FindAllTextBox(ctrl);
You should be able to do this with Page.Form.FindControl("ContentPlaceHolder1").Controls:
foreach (Control item in Page.Form.FindControl("ContentPlaceHolder1").Controls)
{
if (item is TextBox)
{
((TextBox)item).Text = string.Empty;
}
}
This is probably because of your controls are inside of another container when you add a master page. Have you tried adding another foreach before if?
private void ClearControls()
{
foreach(Control container in Page.Controls)
{
foreach (Control c in container.Controls)
{
foreach (Control ctrl in c.Controls)
{
if (ctrl is TextBox)
{
((TextBox)ctrl).Text = string.Empty;
}
}
}
}
}
I wouldn't do it this way though. Sometimes hardcoding is better. This would use a lot of resource when called on a page that contains lots of controls.
Don't hard code:
//Recursively get all the formControls underneath the current one, be it Page, UserControl or whatever.
public static IEnumerable<Control> GetAllControls(this Control parent)
{
foreach (Control control in parent.Controls)
{
yield return control;
foreach (Control descendant in control.GetAllControls())
{
yield return descendant;
}
}
}
Then you can call it in your webform / control:
var formCtls = this.GetAllControls().OfType<TextBox>();
foreach(TextBox txtbx in formCtls)
{
//do what you gotta do ;)
}
First, use operator as instead of is and cast:
TextBox tb = ctrl as TextBox;
if (tb != null)
{
tb.Text = String.Empty;
}
Second, you can use ITextControl instead of TextBox.
And third, try next extension method:
public static IEnumerable<T> GetChildControls(this Control control) where T : Control
{
var children = (control.Controls != null) ? control.Controls.OfType<T>() : Enumerable.Empty<T>();
return children.SelectMany(c => GetChildControls(c)).Concat(children);
}
Usage:
foreach (var c in this.Page.Controls.GetChildControls<TextBox>())
{
c.Text = String.Empty;
}
I had the same problem but I think I was making it too hard. I'm using an AJAX UpdatePanel control and I just referenced that instead of going all the way up to the MasterPage. This worked for me.
foreach (Control c in UpdatePanel1.Controls)
{
foreach (Control c1 in c.Controls)
{
if (c1 is TextBox)
{
TextBox txtBox = (TextBox)c1;
txtBox.Text = "0";
}
}
}
Just keep the controls in Panel, and try the code below
foreach (Control cntrl in pnl.Controls)//pnl is panel id
{
if (cntrl is TextBox)
{
TextBox txtBox = (TextBox)cntrl;
txtBox.Text = " ";
}
}
Make a method on your .cs like this:
//Where "this" is Page.
ClearInput(this);
private void ClearInput(Control parent)
{
foreach (Control c in parent.Controls)
{
if (c.Controls.Count > 0)
ClearInput(c);
else
{
if (c is TextBox)
(c as TextBox).Text = "";
if (c is CheckBox)
(c as CheckBox).Checked = false;
if (c is DropDownList)
(c as DropDownList).SelectedIndex = 1;
}
}
}
private void EnableControls(Control control)
{
var textbox = control as TextBox;
if (textbox != null)
{
textbox.Enabled = true;
}
var dropDownList = control as DropDownList;
if (dropDownList != null)
{
dropDownList.Enabled = true;
}
var radioButton = control as RadioButton;
if (radioButton != null)
{
radioButton.Enabled = true;
}
var checkBox = control as CheckBox;
if (checkBox != null)
{
checkBox.Enabled = true;
}
foreach (Control childControl in control.Controls)
{
EnableControls(childControl);
}
}
public void getAllCtl(ControlCollection ctls)
{
foreach (Control c in ctls)
{
if (c is System.Web.UI.WebControls.TextBox)
{
//TextBox tt = c as TextBox;
////to do something by using textBox tt.
((TextBox)c).Text = string.Empty;
}
if (c is System.Web.UI.WebControls.CheckBox)
{
((CheckBox)c).Checked = false;
}
if (c is System.Web.UI.WebControls.DropDownList)
{
((DropDownList)c).SelectedIndex = -1;
}
if (c.HasControls())
{
getAllCtl(c.Controls);
}
}
}
calling in aspx.cs file as
getAllCtl(this.Form.Controls);
This is OK and tested work for all Master-child page and where ever multiple controls are contains in the page...

Categories

Resources