C# Form Controls - c#

I have a form containing many picture boxes named pb_a1,pb_a2,pb_a3... and so on..
I have a String array containing the picture box names. What I need to do is access each of these and specify an image for it.
Instead of hard coding, I would like to know if there is any way by which I can write a loop which gives me commands like
> Form1.pb_a1.Image=<some Image>;
>
> Form1.pb_a2.Image=<some Image>;
>
> Form1.pb_a3.Image=<some Image>;
>
> Form1.pb_a4.Image=<some Image>;

Can you use the ControlCollection.Find( ) method on the forms Controls property?

if you only have the name of the picture controls and not a reference to them ( which I think you could have kept in a dictionary with name and reference when you created those controls earlier in the form... ), the only way you have I think is to search in the Form.Controls collection until you find the one with the name you are looking for and which is of the picture box type.

You're better off storing the picture boxes in a picture box array, rather than a string array.
PictureBox[] myPictures = {pictureBox1, pictureBox2, pictureBox3, pictureBox4};
foreach (PictureBox picture in myPictures)
{
picture.Image = <some Image>;
}
If you have to have it as a string, the following code may help you out. Please note that I haven't included any error checking incase the element doesn't exist. You're likely to just get an empty element in that part of the array. You may want to encase it in try/catch as well.
string[] myPicturesString = {"pictureBox1", "pictureBox2", "pictureBox3", "pictureBox4"};
PictureBox[] myPictures = new PictureBox[myPicturesString.Length];
for (int i = 0; i < myPictures.Length; i++)
{
foreach (Control c in this.Controls)
{
if (c.Name == myPicturesString[i])
{
myPictures[i] = (PictureBox) c;
}
}
}
MessageBox.Show(myPictures[1].Name);

Assuming that these picturebox are fields of your form, you can reflect (System.Reflection) on the form class, retrieve a reference to the picturebox fields and store them into a dictionary. Do that during form creation (after InitializeComponent).
Next time you have to access a picture box by its name, just use:
myDictionary["pictureboxname"].Image = blabla;

Related

How to retrieve data from dynamically created textboxes and build strings

So I have some code, that creates a row of 4 textboxes. The data from those 4 textboxes will be combined to make a SQL query and then executed. The button to add a row can be hit an infinite amount of times. I have my IDs generated so that on the first click textbox one is txtBox1Row1, then on the second click it is txtBox1Row2 etc, etc.
Now I need a way to retrieve the data from each row and build SQL queries from them. Just to reiterate, I only need the data from the 4 textboxes in each row per loop (I assume thats how this will need to be done).
So how do I go about doing this?
Thanks a lot, the help is always appreciated. I was planning on doing it like this:
foreach (Control c in pnlArea.Controls)
{
if (c.ID.Contains("ddlArea"))
{
area.Add(((DropDownList)c).SelectedValue);
}
if (c.ID.Contains("txtArea"))
{
areaOther.Add(((TextBox)c).Text);
}
if (c.ID.Contains("ddHazard"))
{
hazard.Add(((DropDownList)c).SelectedValue);
}
if (c.ID.Contains("txtHazard"))
{
hazardOther.Add(((TextBox)c).Text);
}
if (c.ID.Contains("txtHazardDesc"))
{
hazardDesc.Add(((TextBox)c).Text);
}
if (c.ID.Contains("txtActionDesc"))
{
actionDesc.Add(((TextBox)c).Text);
}
if (c.ID.Contains("calDueDate"))
{
dueDate.Add(((Calendar)c).SelectedDate);
}
}
Per Nkosi, you'd want to encapsulate your textbox 'area' in a form.
What I would recommend is looping through each textbox in the form and storing in a dictionary.
Here's what that might look like:
Dictionary<string, string> textBoxVals = new Dictionary<string, string>();
Control form = this.FindControl("form1") as Control;
TextBox tb;
foreach (Control c in form.Controls)
{
if (c.GetType() == typeof(TextBox))
{
tb = c as TextBox;
textBoxVals.Add(tb.ID, tb.Text);
}
}
Then you'd be able to loop through the dictionary to build your SQL string. The dictionary would contain both the dynamic name of the control and the value of the textbox.
Based on the code you posted it looks like maybe there are some other controls that might also be associated with each line. If that's the case, you can create another if statement in the foreach loop to handle different control types, so that you're saving the proper parameters of them.
I hope that helps.

Cannot Controls.Find a ComboBox inside a GroupBox

On my Visual C# Form application, I have a combobox inside a groupbox to help organize / look neat. However, once I put the combobox inside the groupbox, I am no longer able to find it by looping through all of the controls on my form.
For example, if I run this code with the Combobox inside the Groupbox I get a different result than if its outside the group box:
foreach (Control contrl in this.Controls)
{
richTextBox1.Text += "\n" + contrl.Name;
}
If the combobox is inside the groupbox, it won't find it.
I also noticed in the Form1.Designer.cs file that whenever I add the combobox inside the groupbox, the following line of code appears to the groupbox:
this.groupBox4.Controls.Add(this.myComboBox);
..
this.groupBox4.Location = new System.Drawing.Point(23, 39);
this.groupBox4.Name = "groupBox4";
... etc...
And this line will be removed:
this.Controls.Add(this.myComboBox);
If I try to edit it manually, it automatically switches back once I move the combobox back inside the groupbox.
Any help would be appreciated! Thanks!
Brian
As you said, you added combo box to group box, so it is added to Controls collection of group box and the designer generates this code:
this.groupBox4.Controls.Add(this.myComboBox);
So if you want to find the combo box programmatically, you can use this options:
Why not simply use: this.myComboBox ?
Use var combo = (ComboBox)this.Controls.Find("myComboBox", true).FirstOrDefault();
Use var combo = (ComboBox)this.groupBox4.Controls["myComboBox"]
Also if you want too loop, you should loop over this.groupBox4.Controls using:
foreach(Control c in this.groupBox4.Controls) {/*use c here */}
this.groupBox4.Controls.Cast<Control>().ToList().ForEach(c=>{/*use c here */})
Just like the Form object, the Group object can hold a collection of controls. You would need to iterate through the Group control's controls collection.
One more idea for getting at all or one ComboBox in a GroupBox, in this case groupBox1. Granted Resa's suggestion for using Find with FirstOrDefault would be best to access one combobox.
List<ComboBox> ComboBoxes = groupBox1
.Controls
.OfType<ComboBox>()
.Select((control) => control).ToList();
foreach (var c in ComboBoxes)
{
Console.WriteLine(c.Name);
}
string nameOfComboBox = "comboBox1";
ComboBox findThis = groupBox1
.Controls
.OfType<ComboBox>()
.Select((control) => control)
.Where(control => control.Name == nameOfComboBox)
.FirstOrDefault();
if (findThis != null)
{
Console.WriteLine(findThis.Text);
}
else
{
Console.WriteLine("Not found");
}
You can use the ControlCollections Find Method, it has a parameter that will search the parent and its Children for your control.
ComboBox temp;
Control[] myControls = Controls.Find("myComboBox", true); //note the method returns an array of matches
if (myControls.Length > 0) //Check that it returned a match
temp = (ComboBox)myControls[0]; //use it

Loop down multiple controls/elements in C# (Store App)

I have multiple images that I want to loop over and set properties of.
Snippet from the xaml, as you can see their names follow up: Life1, Life2, ...
<StackPanel Orientation="Horizontal">
<Image x:Name="Life1"></Image>
<Image x:Name="Life2"></Image>
<Image x:Name="Life3"></Image>
</StackPanel>
What I want is a way to loop over them and set properties.
for (int i = 1; i <= 3; i++) {
Life1.Source = ...
}
How can I add the value of int i to the base name of "Life" and have it interpreted as one of the images?
Thanks in advance!
If I understand you correctly, you have a series of named images in your page and you wish to set the properties for each.
Assuming you have various images in your project stored as Life1, Life2, Life3, etc, then you're really just constructing the name for them based on the prefix ("Life") and an index (I).
Try this:
for (int i=1; i<limit; i++)
{
string name = "Life" + i.ToString();
Image img = (Image)this.FindName(name);
// set properties of img here
}
Assuming that this refers to a current page in your app, this will search the child elements for one with the specified name.
An alternative is simply to iterate over every image in the stackpanel.
If you name the panel, say, "ImageList", then your code can look like this:
foreach (Image item in ImageList.Children)
{
// do stuff to item here
}
If necessary you may query item for its name, and set the properties accordingly.

Is there a way to read hidden text in Microsoft Word?

I am trying to populate a word template in C#. The template contains a table with several cells. I need to be able to identify each cell based on a unique id. I do not find a way to store & read a unique id for each cell/text in word. My approach is to have the unique id as hidden text in each cell. And then format the cell (like changing the background color) based on this unique id.
I face the problem in reading this hidden text in each cell in C#?
Any suggestions would be of great help please!
Thanks!
Here it comes! You can iterate over a document and find a hidden text:
foreach (Microsoft.Office.Interop.Word.Range p in objDoc.Range().Words)
{
if (p.Font.Hidden != 0) //Hidden text found
{
// Do something
}
}
The values returned for p are:
0: Text visible
-1: Text Hidden
That's what I did for a Word Document, but if you are able to iterate over your cells' content, probably this information may help you.
To read hidden text in your code you just need to set
rangeObject.TextRetrievalMode.IncludeHiddenText = true
If you want to make them visible for example, you can iterate trough all words and check the Font.Hidden property, then set it visible:
Word.Document document = ThisAddIn.Instance.Application.ActiveDocument;
var rangeAll = document.Range();
rangeAll.TextRetrievalMode.IncludeHiddenText = true;
foreach (Microsoft.Office.Interop.Word.Range p in rangeAll.Words)
{
texts += p.Text;
if (p.Font.Hidden != 0) //Hidden text found
{
p.Font.Hidden = 0;
count++;
}
}

removing image from a list c#

I am trying to add an image to a list of images when a checkbox is checked, and when the checkbox is unchecked I want to remove the image from the list. Adding the image works fine, but when the box is unchecked its not removing the image from the list.
List<Image> images = new List<Image>();
private void chkRadiation_CheckedChanged(object sender, EventArgs e)
{
if (chkRadiation.Checked == true && images.Count < 4)
{
images.Add(Image.FromFile(#"C:\Users\joe\documents\radiation.gif"));
}
else if (chkRadiation.Checked == false)
{
images = images.Where(x => x != Image.FromFile(#"C:\Users\joe\documents\radiation.gif")).ToList();
}
else if
(chkRadiation.Checked == true)
{
MessageBox.Show("Please select only 3 images");
chkRadiation.Checked = false;
}
}
I also tried
images.Remove(Image.FromFile(#"C:\Users\joe\documents\radiation.gif"));
It did not work either.
What am I doing wrong?
The problem is that you're working with instances of a class Image, so all your comparisons, and images.Remove are working off references.
When you do Image.FromFile(#"C:\Users\joe\documents\radiation.gif") you're creating a new image object/reference, that happens to contains the same data as one in the list, but because the reference isn't the same, removing it won't work.
You might be better to recode using a Generic.Dictionary<String,Image> where the key string is the path of the image (in the absence of any better key). That way you can check if there are items in the dictionary with the path and remove them the same way.
By default List.Remove uses instance value comparision to detect which element to remove. Since you're loading the image again to remove it, that's a different instance. I would keep track of the index in which an image is added and use that to remove it from the list. CheckBox.Tag might be a good place to hide the index...
with the expression
x != Image.FromFile(#"C:\Users\joe\documents\radiation.gif")
you compare two objects:
Object one: x is the image already in your collection.
Object two: is
the image which gets create at this moment based on the source path.
as you compare the two it will always return false as these are two different instances of the object Image.
How the operator == works

Categories