just feeling that i'm wasting loops here = CPU time, and was wondering if there's a way to optimize this code, or just minimize it.
Basically what the code does is, goes trough every controls inside the editOkkInfo control.
checking if the current control is an textbox, if yes, then it will perform some stuff, if no it will jumps to next if-statement. This next statement checks if we have counted 14 times(since i only have 14 textboxes), if not 14, then the loop continues, if counted 14, then the loop breaks.
Any help is appreciated, thanks in advance, and here is the code, cheers.
iterate = 0;
foreach (System.Web.UI.Control ctrl in this.editOkkInfo.Controls)
{
if (ctrl is TextBox)
{
tb = (TextBox)this.FindControl(ctrl.ClientID.ToString());
tb.Text = dt.DefaultView[0][iterate++].ToString();
}
if (iterate == 14)
break;
}
There is no need to use FindControl, as you already have the control. Just cast it:
iterate = 0;
foreach (System.Web.UI.Control ctrl in this.editOkkInfo.Controls)
{
if (ctrl is TextBox)
{
tb = (TextBox)ctrl;
tb.Text = dt.DefaultView[0][iterate++].ToString();
}
if (iterate == 14)
break;
}
An additional readability improvement will do away with the looping over all controls and the is test:
foreach (TextBox ctrl in this.editOkkInfo.Controls)
{
ctrl.Text = dt.DefaultView[0][iterate++].ToString();
if (iterate == 14)
break;
}
You can save your FindControl() parsing by casting the ctrl variable:
tb = (TextBox) ctrl;
tb.Text = //...
And, we should know if editOkkInfo.Controls are created by code or declared in aspx page. If the former is true, you can save a reference to such objects in a variable, then using it instead of looping.
if (ctrl is TextBox)
{
tb = (TextBox)ctrl;
}
this should be enough, you are looking the TextBox using FindControl, knowing that you have it.So, you can just cast the the control to TextBox
I have seen one faster way to find all controls of specific type rather than looping.
This seems more efficient.
Using linq to get list of web controls of certain type in a web page
Hope that helps
Milind
I think instead foreach is better a while, because a while wont check all the controls, until the amount is 14 (could or not check all the controls, depends!)
Related
I have multiple text blocks I want to compare the text values of with whatever the current random value is in my array, so I can "gray out" the text block when it gets "opened".
This code works for 1 text block, but I was wondering how I could do it for all 26 of my blocks w/o having to type out each one? Is there a way I can reference all my blocks, kind of like using the same click event for all my buttons?
if (money[turns]==Convert.ToInt32(tb0.Text))
{
tb0.Foreground = Brushes.Gray;
}
As addition to Alexei, if you want only compare specific TextBlock, first you can insert your TextBlock into a List
List<TextBlock> listTextBlock = new List<TextBlock>();
list.Add(tb0);
list.Add(tb1);
... so you just using loop to check each TextBlock.
foreach(TextBlock item in listTextBlock)
{
if (money[turns]==Convert.ToInt32(item.Text))
{
item.Foreground = Brushes.Gray;
}
}
If Windows.Forms you can iterate through all your controls of type TextBox and compare your text to the one in each TextBox. The code should like this:
bool exists = GetAll(this, typeof(TextBox)).Any(t => t.Text.Equals(yourText));
As already suggested, it would be better to use databinding and do the search in your objects, rather than into your interface.
foreach(Control c in tabAppreciation.Controls)
{
if(c is Button)
{
if((Button)c.Text.ToString()==0)
{
c.BackColor = Color.Green;
}
}
}
I'm getting this error:
Cannot convert type 'string' to 'System.Windows.Forms.Button'
I wanna compare the text of each Button with something and if it matches, change the color of the button, but it seems like I'm not doing it right at all... Can someone help me please?
You could change your code to a simpler
foreach(Button b in tabAppreciation.Controls.OfType<Button>())
{
if(b.Text=="0")
{
b.BackColor = Color.Green;
}
}
This enumerates all the controls of type Button inside the tabAppreciation controls collection and your loop is strongly typed so you don't need anymore the test for Is Button. Notice also that the Text property is already a string and thus applying ToString() makes no sense. Finally a string should be compared to a string (put the zero between double quotes not single quotes that denote a char)
FYI: To use OfType<T>, if it is not already there, you need to add a using System.Linq; directive at the top of in your code file.
Try this:
tabAppreciation
.Controls
.Select( c => c as Button )
.Where( c => c != null )
.Where( b => b.Text.ToString() == "0" )
.ForEach( b => b.BackColor = Color.Green )
;
Arguable easier to read and would have made the issue behind the question less relevent.
foreach(Control c in tabAppreciation.Controls)
{
Button button = c as Button
if(button != null && button.Text == "0")
{
button.BackColor = Color.Green;
}
}
You are almost there. If you do have button controls in the tabAppreciation.Controls collection, then all you need to do is compare the text (you stated in your question: I wanna compare the text of each Button with something and if it matches). So change your code to something like this:
foreach(Control c in tabAppreciation.Controls)
{
if(c is Button)
{
Button button = (Button)c;
if(button.Text=="Button text")
{
c.BackColor = Color.Green;
}
}
}
I am not sure why you check if your text equals a number. If your button text shows a number, then you need to note, that there is a difference between "0" and 0 - the first is of type string and the second of type int (and '0' is again a different type - character).
The ToString() method always returns a string, so it should be easy to construct the condition (rule of thumb) - both sides between a condition operator should have the same type, so after ToString()= it has to come a string - "0" or "text ...".
(Button)c.Text.ToString() is trying to cast the Text property into a button. That is your error. You actually don't need to cast the c object into a Button since the Text property is inherited from ButtonBase which overrides the Text property from the Control Class. The .NET framework is smart enough to know that you mean the overridden Text property not the base one.
To access the c as a button you need to make a new button variable and set its value as c; Button b = c as Button.
You also don't need to call ToString() on a string.
I am writing a C#/ASP.Net web application and I have a large number of text boxes that need to be set to variable values in the code behind. Currently I am doing the following:
AspTextBox0.Text = codeBehindVariable[0];
AspTextBox1.Text = codeBehindVariable[1];
AspTextBox2.Text = codeBehindVariable[2];
AspTextBox3.Text = codeBehindVariable[3];
…
Is there an easy way to do this in a simple “for” loop??
This is a very simplified example, the real program has a switch case and some other testing that needs to be performed at the time the variable is assigned. Therefore, a “for” loop would drastically simplify the writing and maintainability of the code. Back in the good-old-days of VB6 and control arrays this was a piece of cake.
The good old days of VB6 are long gone and better don't come back.
Create a control array or better a List<TextBox> yourself:
var textBoxes = new List<TextBox> {
AspTextBox0,
AspTextBox1,
// ...
};
Then Zip it with the codeBehindVariable:
textBoxes.Zip(codeBehindVariable,
(textBox, variable) => textBox.Text = variable);
Or, if you prefer a for loop:
for ( int i = 0; i < codeBehindVariable.Length; i++ )
{
textBoxes[i].Text = codeBehindVariable[i];
}
Keep in mind that in the for loop you will have to make sure that both textBoxes and codeBehindVariable have the same number of items (or make the loop run only over the shortest list's amount of entries). The Zip function will take care of this by itself.
Assuming you are in a class that implements System.Web.UI.Page you can try to look up the control to find the one you want like so:
for (int i = 0; i <= codeBehindVariable.Length; i++)
{
var textBox = FindControl("AspTextBox" + i, false);
if(textBox != null)
{
textBox.Text = codeBehindVariable[i];
}
}
you can do something like this...
int i = 0;
foreach (Control ctrl in this.Controls)
{
if (ctrl is TextBox)
{
TextBox tempTextBox = (TextBox)ctrl;
tempTextBox.Text = codeBehindVariable[i];
i++;
}
}
In my ASP.NET application I have around 7 to 8 Label controls and currently my code to set their Text value looks like this:
while (MyReader.Read())
{
if(j>=i && j-i<=10 && j<(10+i+a))
{
Label"+[j]+".Text=a;
}
j++;
}
Now my label name statred from 1 to 8, I dont want to repaeat my statements like:
label1.text=a;
label.text=b;
What to do?
Rather than having seven different variables (label1, label2 etc) have one variable of type List<Label> or something similar. Then you can access them by index, iterate over all of them etc.
If you're relying on the designer to declare your variables for you, you could leave them alone but also have a collection variable which you populate in one place. The only problem is that then if you reassign the individual variables, that change won't be reflected in your collection.
As an aside, it looks like you've got your presentation logic and your data access logic in one place - you should consider separating them...
That actually should resolve your issue:
((Label)Page.FindControl("Label" + j)).Text = a;
However as Jon suggested, it would be better to manage your labels in more generic way using list or something.
try this
while (MyReader.Read())
{
if(j>=i && j-i<=10 && j<(10+i+a))
{
Label lbl = new Label();
lbl.Name="Label" + j;
lbl.Text = a;
}
j++;
}
in WPF It it possible to change a text box's font size during runtime?
i tried to do that:
foreach (Control ctrl in gridArray[i].Children)
{
if(ctrl.GetType() == typeof(TextBox))
{
(TextBox)ctrl.FontSize = (double)5;
}
}
but it didnt work
The cast does not have a high precedence, your code effectively tries to cast the value in ctrl.FontSize to TextBox, you need to add parenthesis (and the double cast is superfluous):
((TextBox)ctrl).FontSize = 5;
Further the way you check the type of the control is not such a good idea, use is instead. Otherwise sublasses of TextBox are not included.
if (ctrl is TextBox)
Further as you do not only care about the type and cast as well to interact with the TextBox class interface you may as well use as:
var textBox = ctrl as TextBox;
if (textBox != null)
textBox.FontSize = 5;
This also conveniently gets rid of the parenthesis jungle.