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

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.

Related

Assign x:Name property to a checkbox in source code [Xamarin/C#]

Hello I have set of check boxes that are generated from source code and not in XAML. Now, I wanted to set x:Name during creation of it so that I can loop through each element using the FindByName. I planned on setting name like checkbox1, checkbox2, checkbox3...
So that I can use this FindByName
foreach (var qaItem in question.Entity.QuestionAnswer)
{
(FindByName($"checkbox{qaItem.OrderNum}") as CheckBox).IsChecked = false;
}
Is there a way to set "x:Name" in source? since the number of checkboxes is not definite.
x:Name is not actually a property, it is just a XAML helper that is used to create a C# variable name. If you are creating the elements at runtime, you need to maintain an array or list in order to keep track of them
you could do something like this
Dictionary<string,Checkbox> myCheckboxList = new Dictionary<string,Checkbox>();
then as you create each checbox
var cb = new Checkbox();
... set properties, etc ...
myCheckboxList.Add(qaItem.OrderNum, cb);

Programmatically add views to a programmatically generated view

I am trying to programmatically fill a TableView such that there are 10 TableRows of 4 ImageViews. However, when I try to add ImageViews to the dynamically generated TableRows, nothing appears in the app.
I also need to store each ImageView in an array for later access, or at least store some kind of unique ID for each ImageView in said array.
My code is the following (within my MainActivity):
TableView table = FindViewById<TableLayout>(Resource.Id.tableLayout1);
for(int i = 0; i < 40; i += 4)
{
TableRow row = new TableRow(this);
row.SetGravity(GravityFlags.Center);
for (short j = 0; j < 4; j++)
{
ImageView cell = new ImageView(this);
cell.LayoutParameters = new ViewGroup.LayoutParams(75, 75);
grid[i + j] = cell
row.AddView(cell);
}
table.AddView(row);
}
There are two problems in your code, both stemming from the fact that cells in a TableRow have unique rules about their widths and heights. From the documentation:
The children of a TableRow do not need to specify the layout_width and layout_height attributes in the XML file. TableRow always enforces those values to be respectively ViewGroup+LayoutParams.MatchParent and ViewGroup+LayoutParams.WrapContent.
Even though it's talking about XML layouts, this is true for layouts created in code as well.
So, first, you need something to define the height of your ImageView cells. Generally, you'd use SetImageResource or similar to make sure the src attribute of the image view was defined (note: not the background).
Second, delete this line:
cell.LayoutParameters = new ViewGroup.LayoutParams(75, 75);
After those two changes, your code should work just fine.

Set table values equal to value in other table

I have one table which functions as a viewModel. From this, it is supposed to be the source of my binding in my view. My object is to update this table/viewModel based on two other tables. I have one property from each of the table checklistTable and AnswerTable that is to be set in my viewModel checkViewModel.
At the moment I am querying the current elements I need from each of the tables, and trying to update the viewModel.
CodeBehind:
//Curent descriptions to be set in the viewModel
var currentDescription = (_check.Where(s => currentElements.Contains(s.defineId)).Select(s=> s.Description).ToList());
//Current colors to be set in the viewModel
var currentColors = (from current in _answer
where current.questionId == currentCheckId &&
current.buildingId == currentBuildingId
orderby current.dateReported descending
select current.backgroundColor).ToList();
After retrieving theese values, i try to update my viewModel, and this is where things go wrong:
for (int i =0 ; i < currentDescription.Count() - 1; i++)
{
currentViewTable.Description = currentDescription[i];
}
for (int i =0 ; i < currentColors.Count() - 1; i++)
{
currentViewTable.backgroundColor.Insert(i,currentColors[i]);
}
I get the error: reference not set to an instance of an object. Are there better ways to update my viewModel, of or any tips on what I am doing wrong?
I would first recommend to use a foreach loop instead of a regular for loop. I find it much easier to use foreach when working with lists, this will eliminate any clear "off by one" errors usually.
foreach (var description in currentDescription)
{
//do something given each element in the list
}
This seems to be a data integrity issue from what I can gather just looking at your code and given what the error is stating. I would recommend going into debug mode and looking in the Lists that you have generated to see if there are any indexes where the objects in your two lists are null, and handle these instances accordingly.

How to put my iframe elements in a list?

I have 10 <iframe> elements in my aspx page and they are named f1,f2,.......,f10. What I want to do is to put theme in a list/array so that I can reference them by index.
Please help me with this.
var framearray = document.getElementsByTagName("iframe");
for (var i = 0; i < framearray.length; i++)
{
var aframe = framearray[i];
//do stuff
}
Each control (your Page being one of them) has a Controls property that get a list of all sub-controls.
this.Controls; //will list all sub controls on the page
You can search through that for your items.
Alternately, you can use the FindControl() function on a Control object to get a control based on its ID.
var cnt = this.FindControl("f1");
Copy this line 10 times or make it in a loop, and make them add to an array:
List<Controls> iframeList = new List<Controls>();
for(int i = 1; i <= 10; i++)
iframeList.Add(this.FindControl("f" + i);
<iframe> elements are automatically indexed by the browser in a list object called window.frames, you can iterate this array-like object with a standard for() loop --> https://developer.mozilla.org/en-US/docs/Web/API/window.frames

C# Form Controls

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;

Categories