How to find a LinkLabel or Button on TabPage - c#

I'm trying to put dynamicaly a LinkLabel (also I traied to put a button) in a TabPage:
LinkLabel newLinkLabelButton = new LinkLabel();
newLinkLabelButton.Text = "Login";
newLinkLabelButton.Name = "linkLabel_11";
tabs.TabPages[0].Controls.Add(newLinkLabelButton);
Now I'm trying to find this control on the specificf TabPage with function
newLoginLinkLabel = (LinkLabel)Helper.GetLinkLabelByTagAndfamily(tabs.TabPages[0], _name);
where the function body is:
public static Control GetControlByTagAndfamily(TabPage _tab, string _name)
{
Control rez = new Control();
foreach (Control ctrl in _tab.Controls)
{
if (ctrl.Name == _name)
{
rez = ctrl;
break;
}
}
return rez;
}
But the function never founds a LinkLabel or a Button inside _tab.Controls collection. I observed the collection contains founds Labels only, if I trying to find some labels inside.
Pleas help to solve this.

Well, my problem is solved, the code above is correct. The problem was in wrong _name calculation before using it in
GetControlByTagAndfamily(TabPage _tab, string _name);

Related

Using findControl to find a child element

I have a Placeholder and I have a dynamically created panel in the placeholder, I also have some dynamically added radio buttons in the panel, now I can usefindControl() to find the radio buttons if they are direct children of the placeholder.
I've literally spent the whole of yesterday trying to find them when they are the child elements of the Panel. How is there a way to do this?
Here's my code below:
PlaceHolder1.Controls.Add(myPanel); //add the panel to the placeholderenter code here
myPanel.Controls.Add(myRadioButton); //add the radiobutton to the panel
You should make method that recursively searches for a control using it's Id. That mean that the method will search for a control inside of (in your case) placeholder. If method finds control, it will return it. If not, it will go search every placeholder's subcontrol, going "deeper". And then, if nothing is found, it will search one more level down, in every placeholder subcontrols' subcontrol etc.)
private Control FindControl(string ctlToFindId, Control parentControl)
{
foreach (Control ctl in parentControl.Controls)
{
if (ctl.Id == ctlToFindId)
return ctl;
}
if (ctl.Controls != null)
{
var c = FindControl(ctlToFindId, ctl);
if (c != null) return c;
}
return null;
}
and then use it like this:
Control ctlToFind = FindControl(myRadioButton.Id, Placeholder1);
if (ctlToFind != null)
{
//your radibutton is found, do your stuff here
}
else
{
// not found :(
}
Finding Controls recursive is an option, but it also has a couple of down-sides.
If you know the ID's of all the controls you can just use FindControl
RadioButtonList myRadioButton = PlaceHolder1.FindControl("Panel1").FindControl("RadioButtonList1") as RadioButtonList;
Label1.Text = myRadioButton.SelectedValue;
But you will need to give your dynamically added controls an ID.
Panel myPanel = new Panel();
myPanel.ID = "Panel1";
RadioButtonList myRadioButton = new RadioButtonList();
myRadioButton.ID = "RadioButtonList1";
PlaceHolder1.Controls.Add(myPanel);
myPanel.Controls.Add(myRadioButton);

Accessing variables dynamically in C#

I have tons of Buttons named like this x0y1
How do I access the variable name dynamically so I could loop all names by xiy1 or so.
in PHP it would be like ${"myString" . $randomvar}
I can't use a list or array because the the button already exist defined through the xaml
You can use:
var textbox =
this.Controls.OfType<TextBox>().Where(txb => txb.Name == "myString").FirstOrDefault();
This assumes you are in the context of your form (this.Controls).
And of course, don't forget to add using System.Linq;...
You can get all the textbox using this method
void AllTextBox(System.Windows.Forms.Control.ControlCollection ctrls)
{
foreach (Control ctrl in ctrls)
{
if (ctrl is TextBox)
{
if (ctrl.Name == "textBox1")
{
// do your stuf with textbox
}
}
}
}
You can create function that return control by name :
Control GetControlByName(string Name)
{
foreach(Control control in this.Controls)
if(c.Name == Name) return control ;
return null;
}
or Function with a specific control like that :
Button GetButtonByName(string Name)
{
foreach (Control c in this.Controls.OfType<Button>())
if (c.Name == Name) return c;
return null;
}
For wpf project...
Let's say you have a grid named MyGrid and there's lot of buttons on it.
You want to refer to the button named x0y1:
var btn = MyGrid.Children.OfType<Button>().Where(x=>x.Name=="x0y1");
Note: above code should work for flat structure (one level deep only).
You can achieve the same by using code provided in this thread: How can I find WPF controls by name or type?
Just call FindName("elementName"). FindName searches through all child elements of a FrameworkElement. To access any button by its name as string in a window, call the FindName() method of the window !
If your code is in a class inheriting from Window, just use:
Button button = (Button)FindName("xiy1");
If you write the code in a class not inheriting from Window but FrameworkElement, which is unlikely, use:
Window window = Window.GetWindow(this);
Button button = (Button)window.FindName("xiy1");
Check the MSDN documentation about Namescopes for more information about limitations.

Using labels like arrays

I am working on winform application in asp.net using c#. I have 10 labels on my winform created in the designer mode, called Label0 to Label9. Now I want to change the Text property of all the labels at once as per the data I acquire in the middle of execution of my program.
i want to do something like this :
for (int i = 0; i < 10; i++)
{
Label[i].Text = "Hello, this is label: "+ i.ToString();
}
Now, of course this won't work. But how can this be done? how can i call the label like its done in an array? If not possible, then what can be the best alternative solution for my problem?
If you are talking about WinForms, then you can do like this:
private void Form1_Load(object sender, EventArgs e)
{
// Form1_Load is just sample place for code executing
for (int i = 1; i < 10; i++)
{
var label = Find<Label>(this, "label" + i);
label.Text = "Hello, this is label: " + i.ToString();
}
}
private T Find<T>(Control container, string name)
where T : Control
{
foreach (Control control in container.Controls)
{
if (control is T && control.Name == name)
return (T)control;
}
return null;
}
This code will search label in form controls, and then return it based on control name and type T. But it will use just parent form. So if your label is in some panel, then you need to specify panel as container parameter. Otherwise Find method can be updated as recursive method, so it will search inside all form subcontrols, but if there will be two Label1 controls, then it will return just first one, that might be not correct.
If you can put all Label on a panel after the you can use below code to change the text
foreach (Control p in panal.Controls)
if (p.GetType == Label)
p.Text = "your text";

Change text property of all items in form

I have many buttons and labels on my c# form. I have a button that changes all butons' and labels' text properties (change language button). Do i have to write all items in click event of button or is there a method that scans all form control items and change their text properties.
There are many other controls that contains labels or buttons. For example a label is added to the control of a panel and when i iterate form controls, i can't reach this label. I want to change all items' text properties at one time.
Thank you.
foreach (Control objCtrl in yourFormName.Controls) {
if (objCtrl is Label)
{
// Assign Some Text
}
if (objCtrl is Button)
{
// Assign some text
}
}
If a CS0120 error happens, change yourFormName.Controls to this.Controls;
Assuming ASP.NET's ITextControl Interface (works similar for Winforms-Controls' Text-Property ):
var text = "Hello World";
var allTextControls = this.Controls.OfType<ITextControl>();
foreach(ITextControl txt in allTextControls)
txt.Text = text;
http://msdn.microsoft.com/en-us/library/bb360913.aspx
Edit: You could easily make it an extension(e.g. ASP.NET, for Winforms replace ITextControl with Control):
public static class ControlExtensions
{
public static void SetControlChildText(this Control rootControl, String text, bool recursive)
{
var allChildTextControls = rootControl.Controls.OfType<ITextControl>();
foreach (ITextControl txt in allChildTextControls)
txt.Text = text;
if (recursive) {
foreach (Control child in rootControl.Controls)
child.SetControlChildText(text, true);
}
}
}
Now you can call it for example in this way:
protected void Page_Load(object sender, EventArgs e)
{
Page.SetControlChildText("Hello World", true);
}
This will apply the given text on every child control implementing ITextControl(like Label or TextBox).
If it's winforms you should read about localizing your application here:
Walkthrough: Localizing Windows Forms
I think if you are using javascript, you can simply go through the DOM and modify the texts of the buttons and labels. Using jQuery this will be very simple
For a web application, you could do this quite easily with jQuery. Have a look at this: http://api.jquery.com/category/selectors/
$('label').each(function(){this.value = 'something else';});
For Winforms, you can use this:
foreach (var c in Controls.OfType<TextBox>())
c.Text = "TextBox Text";
foreach (var c in Controls.OfType<Label>())
c.Text = "Label text";
But I agree with #ionden, you should consider localizing your application.
There is a Controls property that contains all controls of your form. You can iterate over it:
foreach(var control in Controls)
{
var button = control as Button;
if(button != null)
button.Text = Translate(button.Text);
else
{
var label = control as Label;
if(label != null)
label .Text = Translate(label .Text);
}
}
foreach( Control ctlparent in this.Controls)
{
if(ctlparent is Panel or ctlparent is GroupBox)
{
foreach(Control ctl in ctlparent.Controls)
{
if(ctl is Label or ctl is Button)
{
ctl.Text= newtext;
}
}}
This will work.

Problems changing properties on a control using the controls name

This should work.. I think..
string ctrlName = "btnSomeButton" + someIndexValue;
this.Controls[ctrlName].Text = "Some value";
I get 'Object reference not set to an instance of an object.', the control does exist on the form. I've tried casting it.
Solution:
string ctrlName = "btnSomeButton" + someIndexValue;
Control[] ctrl = this.Controls.Find(ctrlName, True);
Button btn = (Button)ctrl[0];
btn.Text = "Some Value";
Thank you.
The control might be a nested control so you're going to have to dig deeper in the control tree of "this"
Here is a simple recursive control search tool, i wrote it without testing it but i think it should work for your needs:
private Control FindControl(Control ctr, string name)
{
Control c = null;
for (int i = 0; i < ctr.Controls.Count; i++)
{
if (string.Equals(ctr.Controls[i].ID, name, StringComparison.CurrentCultureIgnoreCase))
{
c = ctr.Controls[i];
break;
}
if (ctr.Controls[i].Controls.Count > 0)
{
c = FindControl(ctr.Controls[i], name);
if (c != null)
break;
}
}
return c;
}
Are your buttons actually controls on the form, or do they have a different parent? For instance, if you buttons reside inside a a Panel or GroupBox you will not be able to access them by name by just using this. You will need to find them in their container.
Example: myPanel.Controls[ctrlName].Text = "Some Value"
You can use the control methods in addition to this below to determine where the control is located i.e. what parent might have this control assigned.
{
Control[] ctls = this.Controls.Find("Button2", true);
if (ctls.Length > 0)
{
Button btn = ctls[0] as Button;
if (btn != null)
btn.PerformClick();
}
else
MessageBox.Show("Not Found");
}
private void button2_Click(object sender, EventArgs e)
{
MessageBox.Show("Button2 Clicked");
}
Depending on your requirements, you may want to consider creating a Dictionary<string, Control> collection that allows you to quickly refer to the control by name. This also frees you from requiring the control name containing the index.
Do you really have a control named like ctrlName in your immediate Controls collection? It may be the name of a control that is deeper in the hierarchy, or even a control which doesn't exist.
Try finding the control recursively:
string ctrlName = "btnSomeButton" + someIndexValue;
Control[] matchingControls = this.Controls.Find(ctrlName, true);
foreach (Control c in matchingControls)
c.Text = "Some value";

Categories