Get only the groupBoxes from a winform - c#

i made this code for get all the groupboxes from a winform and then take only the ones with a determinated name.
Control.ControlCollection controles = this.Controls;
GroupBox gBoxAux = new GroupBox();
List<GroupBox> gBoxes = new List<GroupBox>();
foreach (Control c in controles)
{
if (c.GetType() == typeof(GroupBox))
{
gBoxAux = (GroupBox)c;
gBoxes.Add(gBoxAux);
}
}
I don't know if there's a better way to do it instead of iterate over all the controls.
Thank you very much!

You can query that using Linq:
this.Controls.OfType<GroupbBox>().Where(x=> x.Name == "SomeName").ToList();

Well to find all groupboxes there is no better way than to iterate over all of them. But (for me) the code would look better with this:
List<GroupBox> gBoxes = this.Controls.OfType<GroupbBox>().ToList();
OfType<T> selects all elements of a sequence that are of that type.
Note that this only finds all groupboxes directly contained in this ControlCollection but not in sub-containers. You may want to collect the groupboxes recursively:
public IEnumerable<GroupBoxes> GetAllGroupBoxes(Control c)
{
return c.Controls.OfType<GroupBox>()
.Concat(c.Controls.OfType<Control>().SelectMany(GetAllGroupBoxes));
}
List<GroupBox> gBoxes = GetAllGroupBoxes(this).ToList();
To filter for a specific name you can use Where:
Controls.OfType<GroupBox>().Where(gb => gb.Name == "whatever")...

Related

Align the text in center for multiple richtextbox in c#

I need to align the text center for multiple richtextbox.
I found the solution to align the single richtextbox.
EX:
richtextbox1.SelectAll();
richtectbox1.SelectionAlignment = HorizantalAlignment.Center;
I dont want to enter this for every textboxes.
How to do this for multiple richtextbox using loop?
You can look for all the controls who are of type RichTextBox and do whatever you need to do like this:
foreach (var thisControl in this.Controls.OfType<RichTextBox>())
{
thisControl.SelectAll();
thisControl.SelectionAlignment = HorizontalAlignment.Center;
}
In addition to CodingYoshi's answer, if the Rich Text Boxes don't have a single common parent (i.e. the TextBoxes are dispersed on GroupBoxes, Tabs, etc), then you'll need to recurse from the topmost common parent (possibly the form itself) in order to find the RichTextBoxes, using a technique such as this one here:
public IEnumerable<Control> GetAll(Control control, Type type)
{
var controls = control.Controls.Cast<Control>();
return controls.SelectMany(ctrl => GetAll(ctrl, type))
.Concat(controls)
.Where(c => c.GetType() == type);
}
You'll then be able to apply your alignment to all subordinate controls at any level from a given root coontrol (this is the root Form control in this example)
foreach (RichTextBox textBox in GetAll(this, typeof (RichTextBox)))
{
textBox.SelectAll();
textBox.SelectionAlignment = HorizontalAlignment.Center;
}
You need to create a list of RichTextBoxes, and then:
foreach(richtextbox in list)
{
t.SelectAll();
t.SelectionAlignment = HorizantalAlignment.Center;
}
You can also use [this] (How to get ALL child controls of a Windows Forms form of a specific type (Button/Textbox)?) post, to gather all your richtextboxes:
First you need to get all the child controls of the form into a list, and by changing the required property of each item in the list your objective can be met.
You can get all child controls by using a function like this:
public static IEnumerable<TControl> GetChildControls<TControl>(this Control control) where TControl : Control
{
var children = (control.Controls != null) ? control.Controls.OfType<TControl>() : Enumerable.Empty<TControl>();
return children.SelectMany(c => GetChildControls<TControl>(c)).Concat(children);
}
You can get all the RichText boxes like this
var richTextBoxes = this.GetChildControls<RichTextBox>();
foreach (RichTextBox rtb in richTextBoxes)
{
rtb.SelectionAlignment = HorizantalAlignment.Center;
}
Consider this as an idea, copy paste this code may have syntax errors.

Array of ListBox Names from a Tab C#

I have a tab control that has listboxes on it some of which are created and named dynamically so I can't statically program their name. Is there a way to create an array of all the list box names on a give tabPage? I have been going nuts trying to figure out a way to do it.
it would look something like this (based on a winforms example)
List<string> listBoxNames = new List<string>();
foreach (Control control in tabPage1.Controls)
{
if (control.GetType() == typeof(ListBox))
{
listBoxNames.Add(control.Name);
}
}
Or the same thing in linq syntax
List<string> listBoxNames = (from Control control in tabPage1.Controls
where control.GetType() == typeof (ListBox)
select control.Name).ToList();
if you want to find all the listbox's in the tabpage again then see below
foreach (var listBoxName in listBoxNames)
{
ListBox listBox = (ListBox) tabPage1.Controls.Find(listBoxName, true)[0];
}

Store textbox values in an array in c#

I have a form with 10 TextBoxes and OK button.
When the OK button was clicked. I need to store the values from the textboxes to a string of array.
Can someone help me please?
I need to store the values from the textboxes to a string of array.
string[] array = this.Controls.OfType<TextBox>()
.Select(r=> r.Text)
.ToArray();
The above expects the TextBoxes to be on the Form directly, not inside a container, if they are inside multiple containers then you should get all the controls recursively.
Make sure you include using System.Linq;.
If you are using lower frameworks than .Net Framework 3.5. Then you can use a simple foreach loop like:
List<string> list = new List<string>();
foreach(Control c in this.Controls)
{
if(c is TextBox)
list.Add((c as TextBox).Text);
}
(this would work with .Net framework 2.0 onward)
To get all textboxes not only the direct childs of the form (this)
Func<Control, IEnumerable<Control>> allControls = null;
allControls = c => new Control[] { c }.Concat(c.Controls.Cast<Control>().SelectMany(x => allControls(x)));
var all = allControls(this).OfType<TextBox>()
.Select(t => t.Text)
.ToList();

What is a smarter way to get a child control in XAML?

I have a User Control, containing a Grid, containing a child control.
I want to get a reference to the child control from the code behind for the User Control.
This is what I have:
var childControl = (MyChildControlType)this.Grid.Children.Single(c => (string) c.GetValue(NameProperty) == "MyChildControlNameFromXAMLNameAttribute");
Ugly as a run over garbage can lid.
What is a neater way to do this?
You could either go with the name-hunting, along the lines of what's been suggested already:
var childControl = (MyChildControlType)this.Grid.FindName("MyChildControlNameEtc");
Or, if you wanted a more generic approach to what you're already trying (eg if you want to look up by a different property), you could try:
var childControl = (MyChildControlType)this.Grid.Children.OfType<FrameworkElement>().Single(f => f.Name == "Blah");
or
var childControl = (MyChildControlType)this.Grid.Children.OfType<MyChildControlType>().Single(f => f.Name == "Blah");
Or you could use the VisualTreeHelper, which would work with non-Grids, and would particularly work nicely if you needed to recurse down the visual tree:
for(int i = 0; i < VisualTreeHelper.GetChildrenCount(this.Grid); ++i)
{
var child = VisualTreeHelper.GetChild(this.Grid, i) as FrameworkElement;
if (child != null && child.Name == "Blah")
return child;
}
But really if you can just name it and access it from the codebehind normally like what John Bowen said that's by far the easiest.
Assigning a Name or x:Name to an element in XAML (unless it is inside a template) makes that element accessible from code-behind as a field with that name. So this is basically already declared and populated for you during InitializeComponent:
MyChildControlType MyChildControlNameFromXAMLNameAttribute;
and you can use it directly:
MyChildControlNameFromXAMLNameAttribute.Visibility = Visibility.Hidden;
May be this , Give x:Name to your childControl
var childControl = (MyChildControlType)MyGridNameFromXAMLNameAttribute.FindName("MyChildControlNameFromXAMLNameAttribute");

Loop through Textboxes

I have a winforms app that has 37 textboxes on the screen. Each one is sequentially numbered:
DateTextBox0
DateTextBox1 ...
DateTextBox37
I am trying to iterate through the text boxes and assign a value to each one:
int month = MonthYearPicker.Value.Month;
int year = MonthYearPicker.Value.Year;
int numberOfDays = DateTime.DaysInMonth(year, month);
m_MonthStartDate = new DateTime(year, month, 1);
m_MonthEndDate = new DateTime(year, month, numberOfDays);
DayOfWeek monthStartDayOfWeek = m_MonthStartDate.DayOfWeek;
int daysOffset = Math.Abs(DayOfWeek.Sunday - monthStartDayOfWeek);
for (int i = 0; i <= (numberOfDays - 1); i++)
{
//Here is where I want to loop through the textboxes and assign values based on the 'i' value
DateTextBox(daysOffset + i) = m_MonthStartDate.AddDays(i).Day.ToString();
}
Let me clarify that these textboxes appear on separate panels (37 of them). So in order for me to loop through using a foreach, I have to loop through the primary controls (the panels), then loop through the controls on the panels. It starts getting complicated.
Any suggestions on how I can assign this value to the textbox?
To get all controls and sub-controls recursively of specified type, use this extension method:
public static IEnumerable<TControl> GetChildControls<TControl>(this Control control) where TControl : Control
{
var children = (control.Controls != null) ? control.Controls.OfType<TControl>() : Enumerable.Empty<TControl>();
return children.SelectMany(c => GetChildControls<TControl>(c)).Concat(children);
}
usage:
var allTextBoxes = this.GetChildControls<TextBox>();
foreach (TextBox tb in allTextBoxes)
{
tb.Text = ...;
}
You Could loop all the controls in the form asking one by one if it is a "Textbox" y ther return the complete List of them.
public List GetTextBoxes(){
var textBoxes = new List();
foreach (Control c in Controls){
if(c is TextBox){
textBoxes.add(c);
}
}
return textBoxes;
}
You can loop through the textboxes in your form in a fairly simple manner:
Func<ControlCollection, List<TextBox>> SearchTextBoxes = null;
SearchTextBoxes = coll => {
List<TextBox> textBoxes = new List<TextBox>();
foreach (Control c in coll) {
TextBox box = c as TextBox;
if (box != null)
textBoxes.Add(box);
if (c.Controls.Count > 0)
textBoxes.AddRange(SearchTextBoxes(c.Controls));
}
return textBoxes;
};
var tbs = SearchTextBoxes(this.Controls).OrderBy(tb => tb.Name);
Edit: Changed according to new requirements. Not nearly as elegant as the LINQ-solution, of course :)
Since this post seems to resurrect itself from time to time and since the solutions above do not find controls inside of controls, such as in a groupbox, this will find them. Just add your control type:
public static IList<T> GetAllControls<T>(Control control) where T : Control
{
var lst = new List<T>();
foreach (Control item in control.Controls)
{
var ctr = item as T;
if (ctr != null)
lst.Add(ctr);
else
lst.AddRange(GetAllControls<T>(item));
}
return lst;
}
And it's use:
var listBoxes = GetAllControls<ListBox>(this);
foreach (ListBox lst in listBoxes)
{
//Do Something
}
Iterate through controls within form and check name of the control if matched then set Text property as you require.
int i = 0;
foreach (Control contrl in this.Controls) {
if (contrl.Name == ("DateTextBox" + i.ToString())) {
contrl.Text = "requiredtexttobeset";
}
i = i + 1;
}
If you want to do without 'foreach' (If you have specific boxes to adjust/address)
int numControls = Page.Form.Controls.Count;
for (int i = 0; i < numControls; i++)
{
if (Page.Form.Controls[i] is TextBox)
{
TextBox currBox = Page.Form.Controls[i] as TextBox;
currbox.Text = currbox.TabIndex.ToString();
}
}
//THE EASY WAY! Always post easy solutions. It's the best way.
//This code is used to loop through all textboxes on a form for data validation.
//If an empty textbox is found, Set the error provider for the appropriate textbox.
foreach (var control in Controls)
{
if (control is TextBox)
{
//Box the control into a textbox. Not really needed, but do it anyway
var textbox = (TextBox)control;
if (String.IsNullOrWhiteSpace(textbox.Text))
{
//Set the errorProvider for data validation
errorProvider1.SetError(textbox, "Data Required!");
textbox.Text = String.Empty; //Clear out the whitespace if necessary
//blnError = true;
}
}
}
You can simply do this mate...
foreach (TextBox txt in this.Panel.Controls.OfType<TextBox>())
{
txt.Text="some value you assign";
}
If your text boxes are on the form directly and not on a Panel then you can replace this.Panel.Controls with this.Controls. That should be short and clear enough for you.
After the InitialiseComponents() call, add the textboxes to a collection member variable on the form. You can then iterate through them in order later on.
You can create a Dictionary of TextBox, int like the following
Dictionary<TextBox, int> textBoxes = new Dictionary<TextBox, int>();
foreach (TextBox control in Controls.OfType<TextBox>())
textBoxes[control] = Convert.ToInt32(control.Name.Substring(11));
Now.. to loop through them..
foreach (var item in textBoxes.Select(p => new { textBox = p.Key, no = p.Value}))
item.textBox.Text = item.no.ToString(); // whatever you want...
Good luck!
Since you already know the name of control, therefore you can search the control by its name.
See Get a Windows Forms control by name in C#
Other answers just not cutting it for you?
I found this as an answer to a similar question on SO, but I can't find the thread now. It recursively loops through ALL controls of a given type which are located within a control. So includes children of children of children of... etc. My example changes the ForeColor of each TextBox to Hot Pink!
public IEnumerable<Control> GetAllControlsOfType(Control control, Type type)
{
var controls = control.Controls.Cast<Control>();
return controls.SelectMany(ctrl => GetAllControlsOfType(ctrl, type))
.Concat(controls)
.Where(c => c.GetType() == type);
}
Implementation:
IEnumerable<Control> allTxtBxs = GetAllControlsOfType(this, typeof(TextBox));
foreach (TextBox txtBx in allTxtBxs)
{
txtBx.ForeColor = Color.HotPink;
}
Quite similar to abatishchev's answer(which, for me, only returned first-level child controls), but different enough to merit it's own answer I think.

Categories

Resources