How to change property of usercontrol dynamically in loop - c#

1I have problem that I am going to work with usercontrol in loop. In other word II want to change usercontrols property, but I cant. So I have usercontrol named ucProperty and in it many labels. I have called all of them differently such as LblNameModel, LblImageName, ... In my form there are many usercontrols - ucProperty1,2,.8 and now I want to change their properties (LblNameModel, LblImageName,..) dynamically and in loop.
I try this:
int i = 1;
foreach (Control contrl in this.Controls)
{
if (contrl.Name == ("ucProperty" + i.ToString()))
{
contrl.LblNameModel = "Model" + i.ToString();
contrl.LblImageName = "image" + i.ToString() + ".jpg";
i++;
}
}
enter image description here LblNameModel isnt accepted
But it doesnt work. My problem is properties as LblNameModel after contrl. isnt accepted to programm.
How I can change the properties in loop
and in my usercontrol ucProperty there is the code:
public string LblNameModel
{
get { return lblNameModel.Text; }
set { lblNameModel.Text = value; }
}
this is next result

You must filter and cast to your user controls
using System.Linq;
...
foreach (var uc in this.Controls.OfType<MyUserControlType>())
{
string number = uc.Name.SubString("ucProperty".Length);
uc.LblNameModel = "Model" + number;
uc.LblImageName = "image" + number + ".jpg";
}
If you simply loop through the controls, you get a loop variable typed as Control and you are not able to access properties specific to your user control. The OfType<T> extension method (namespace System.Linq) does both, filter and cast.
I assume that all of these user controls are named as ucProperty<number>. Otherwise add the check
if (uc.Name.StartsWith("ucProperty"))
Note that your approach with i has a problem if the user controls do not appear in the right order. I.e. If the foreach yields "ucProperty4" but i is 3 then this control will be skipped.

Related

C# Updating multiple text boxes with similar names

I have multiple textbox names such as R1TotalCost, R2TotalCost, R3TotalCost, all the way up to R25TotalCost. Is there anyway to edit the text values, and or text colours to them all using a code simular to this
for (i=1; i <=25, i++) {
string TextBoxName ="R" + i + "TotalCost";
TextBoxName.text = "£25";
TextBoxName.Foreground = Brushes.Green;
}
I think the best way to go about this since you seem to want to update them all at once, would be to create an Array or List that contains all of the TextBox elements. Then your can go through them all like below!
foreach (TextBox tb in myTextBoxes) {
tb.Content = "UPDATED CONTENT!";
}

How to use int i for selecting text box NR

I have 10 text boxes. Like textBox1.Text , textBox2.Text and so on. I need to use textBox2.Text if i=2, textBox2.Text if i =3 and so on.
I did:
string t = "textBox"+i+".Text";
But outcome coming as "textBox1.Text".
How to insert 'i' Value into textBox name instead of 1. And get the outcome as textBox1.Text
So I can use it as name and pass value from textbox to my program.
Based on what I think you are asking, you could store a reference to each TextBox in an array and then use your int to reference it.
TextBox[] boxes = new TextBox[10];
boxes[0] = textBox1;
// ... follow the pattern
boxes[9] = textBox10;
string value = boxes[i-1].Text; // Gets the value of the textBoxi.Text
You can do it like so:
private TextBox GetTB(int i) {
string name = "textBox" + i.ToString();
foreach (var ctrl in Controls) {
var tbox = ctrl as TextBox;
if (tbox?.Name == name) return tbox;
}
return null
}
The easiest way, if you need to access them in C# code this way, would be to maintain an array or List of these textboxes, indexed in order of their numeric value. Then you could simply reference textBoxes[i-1] and get the textbox numbered "i". How you get that array depends on exactly what you're developing. For WinForms, you can use a little Linq on the Form.Controls property:
public static IEnumerable<Control> Flatten(this IEnumerable<Control> controls)
{
var results = new List<Control>();
foreach (var control in controls)
{
results.Add(control);
control.Controls.OfType<Control>().Flatten(results);
}
return results;
}
private static void Flatten(this IEnumerable<Control> controls, List<Control> results)
{
foreach (var control in controls)
{
results.Add(control);
control.Controls.OfType<Control>().Flatten(results);
}
}
...
var textboxes = Form.Controls.Flatten()
.OfType<TextBox>()
.Where(t=>t.Name.StartsWith("textBox"))
.OrderBy(t=>t.Name)
.ToArray();

Check fields for null entry and change field background to lightyellow?

Great website - very helpful in my C# Class.
I am trying to write a method in C# that will Check fields for null entry and change field background to LightYellow?
The form is a display form that views records in a SQL database.
Here is what I tried - but the variable for the field names isn't translating to the field name.
Advice?
// YellowBack Method fills background of key fields that are missing data or are NULL
private void YellowBack()
{
//Bool fieldContents = true;
string fieldVariable;
string[] fieldName = { "activity_TitleTextBox", "act_Title2TextBox", "kid_NotesTextBox", "review_AdultTextBox",
"phoneTextBox", "addressTextBox", "cityTextBox", "websiteTextBox", "weblink_TextTextBox",
"hoursTextBox", "admissionTextBox" };
int count = 0;
//Check each field name
for (int index = 0; index < fieldName.Length; index++)
{
fieldVariable == fieldName.Text;
if (fieldVariable.Trim = "")
{
fieldVariable.BackColor = LightYellow;
}
else
{
fieldVariable.BackColor = Window;
}
}
}
You are not using the index . . . . you should be using something like:
fieldVariable = fieldName[i].Text;
I also think that you won't be able to set the property BackColor on fieldVariable as it is a string. You should probably be using the object grid or text control that your database binds to and setting the color properties of that . . . but I'm not sure there's enough information here to go on.
I think the problem is that you're looping through a list of strings and trying to make the string into a TextBox control. Instead, you should probably loop through all the controls on the form, and for each one that is a TextBox, see if it's name matches a name in your list. Then you can set the back color of the control based on the Text property.
There are other problems with your code also, like in your if statement you are doing an assignment (=) instead of a comparison (==).
Here's what I would do:
private void HighlightEmptyFields()
{
// Create a list of all the text box names that we want to examine
var textBoxNames = new List<string>
{
"activity_TitleTextBox", "act_Title2TextBox", "kid_NotesTextBox",
"review_AdultTextBox", "phoneTextBox", "addressTextBox", "cityTextBox",
"websiteTextBox", "weblink_TextTextBox", "hoursTextBox", "admissionTextBox"
};
// Loop through every control on the form
foreach (Control formControl in this.Controls)
{
// Find the groupbox control by name
if (formControl.Name != "groupBox1") continue;
// We found the group box, so loop through every control in it
foreach (Control groupBoxControl in formControl.Controls)
{
// Try to cast the control to a TextBox.
var textBoxControl = groupBoxControl as TextBox;
// If the cast fails, move on to the next one...
if (textBoxControl == null) continue;
// Now we have one a textbox control, so see if the
// textBoxNames array contains the name of this text box.
if (textBoxNames.Contains(textBoxControl.Name,
StringComparer.OrdinalIgnoreCase))
{
// We found a match, so set the backcolor based on Text property
if (textBoxControl.Text.Trim() == "")
{
textBoxControl.BackColor = Color.LightYellow;
}
else
{
textBoxControl.BackColor = Color.White;
}
}
}
// Since we found the control we were looking for, we can stop looking
break;
}
}

set combobox text from textbox

I have user submitted content that is loaded into c# winform in our office for processing before officially added to database. The user can submit a 'Referrer' as two text fields-first and last name. In the office I want to have a combobox will all existing referrers loaded in, then the first couple letters of the name to advance the combobox down to the area it needs to be at. I want to do something like this, taking the first two letters of the name and use that to initialize the combobox.
if (txtrefFirstName.TextLength > 2)
{
string firstStart = "" + txtrefFirstName.Text[0] + txtrefFirstName.Text[1];
firstStart = firstStart.ToUpper();
ddlReferring.SelectedText.StartsWith(firstStart);
}
else
ddlReferring.Text = "";
Any ideas or suggestions to get this to work?
Thanks
David K.
You could write something like this...
foreach (string item in ddlReferring.Items)
{
if (item.StartsWith(firstStart))
{
ddlReferring.SelectedText = item;
break;
}
}
Assuming the ddl's datasource is a List of String objects, you should be able to do some comparison on the datasource itself. I tend to use Linq for things like this but it isn't strictly necessary, just shorter.
if (txtrefFirstName.TextLength > 2)
{
string firstStart = txtrefFirstName.Text.Substring(0,2).ToUpper();
string Selection = ddlReferring.DataSource.Where(a=>a.StartsWith(firstStart)).FirstOrDefault();
ddlReferring.SelectedText = Selection ?? "";
}
else
ddlReferring.Text = "";
The selection line can also come from the items collection directly
string Selection = ddlReferring.Items.OfType<string>().Where(a=>a.StartsWith(firstStart)).FirstOrDefault();
Or if you REALLY dont want to use Linq...
string Selection = "";
foreach (object item in ddlReferring.Items)
if (item.ToString().StartsWith(firstStart))
{
Selection = item.ToString();
break;
}
Similar methods can be used even if the ddl's data is not a list of strings, just make sure to cast the items appropriately and compare the correct values.

How to read contents of many textboxes to an array?

I have to write a program (C#, WPF), where data is retrieved from ~30 TextBoxes. I'd like to cycle the textboxes through. I tried to create an array of textboxes, but it didn't work very well because in every method I had to repeatedly reinitialize this array.
TextBox[] subjects = { textBox1, textBox2, textBox3, textBox4, textBox5, textBox6, textBox7, textBox8, textBox9, textBox10 };
TextBox[] credits = { textBox11, textBox12, textBox13, textBox14, textBox15, textBox16, textBox17, textBox18, textBox19, textBox20 };
TextBox[] marks = { textBox21, textBox22, textBox23, textBox24, textBox25, textBox26, textBox27, textBox28, textBox29, textBox30 };
Subject.SubjectName = subjects[selection].Text;
Subject.AmountOfCredits= Convert.ToInt32(credits[selection].Text);
Subject.Mark = Convert.ToInt32(marks[selection].Text);
Main question is, if there is any other way to cycle through all those controls without creating arrays of textboxes?
Thanks in advance.
You could bind each textbox to a property. Then in the setter of each property, you would set the appropriate value in your array.
public class test
{
private string[] _textBoxes;
// constructor
public test()
{
_textBoxes = new string[30];
}
// bind your textboxes to a bunch
// of properties
public string Property0
{
get
{
return _textBoxes[0];
}
set
{
_textBoxes[0] = value;
OnPropertyChanged("Property0");
}
}
}
Have you considered using a DataGrid control? You could have three columns (Subjects, Credits and Marks) and easily get to the selected record via the SelectedItem property?
The other option is to use an ItemsControl. You could style the ItemTemplate to have three textboxes, which you databind to the properties of Subject directly. The ItemsControl's ItemsSource would then be bound to an observable collection of Subjects. For more information on how to do this, go to Microsoft's help on Data Templating Overview.
Can't you make the arrays global to the form rather than local to a method? That way you would only create the arrays once (perhaps inside the form's Load() event).
If making the control arrays global is not an option, you could lookup the controls by name (although this is somewhat slower than your array method)
string idx = (selection + 1).ToString(); // convert selection to 1-based index string
TextBox subjectText = (TextBox)FindControl("textBox" + idx);
TextBox amtCreditsText = (TextBox)FindControl("textBox1" + idx);
TextBox marksText = (TextBox)FindControl("textBox2" + idx);

Categories

Resources