Foreach Question - c#

I am trying to use a foreach statement. I would like to be able to do something like this:
foreach (int item in itemcount)
{
label{0}.Text = item.ToString()
}
Where {0} would be the number that is in item.
Is this possible?

You can do something like this:
foreach (int item in itemcount)
{
Controls[string.Format("label{0}", item.Id)].Text = item.ToString();
}
Also, if you need to access properties of the label class you need to cast the left expression to Label class.

If your class is an ASP.NET page then you should be able to find it with FindControl:
foreach (int item in itemcount)
{
string name = string.Format("label{0}", item);
Label label = FindControl(name) as Label;
if (label != null)
{
label.Text = name;
}
}

If you're trying to programmatically access a variable name, you need to use Reflection.

Off the top of my head, the answer is no. As you do not have access to the iterator the foreach loop is using.
Instead do something like this
IList<Label> labels = new ArrayList<Label>();
for(int i = 0;i<labels.count;i++)
{
labels[i].text = i.toString();
}

Is "label" an array? Then you should do this :
label[item] = item.ToString();
And if label is not an array, probably you should use an array instead of using variable names like label0, label1, ... it would be a lot easier than using reflection.

foreach (int item in itemcount)
{
label[label.IndexOf(item)].Text = item.ToString()
}
If I need to assume that "label" is a list of labels (List/IList), you've an indexer accessed with [], and lists have an IndexOf method accepting a given existing object in the whole list that returns the index of the "item" - in the list -, as you can check in MSDN:
http://msdn.microsoft.com/en-us/library/5y536ey6.aspx (IList interface, see methods section).

Just for the sake of throwing answers, depending on itemcount type, you could write:
Array.ForEach(itemcount, item => label[Convert.ToInt32(item)].Text = item.ToString());
if itemcount is an object[], or
itemcount.ForEach(item => label[Convert.ToInt32(item)].Text = item.ToString());
if itemcount is a List<object>.

While code such as those examples posted earlier does in a strict sense answer the question, it seems like really, really poor design to go down that path.
Depending on your needs, and what framework you are using, you are much better off using some other technique. Arrays of controls are one option; if you're using WPF then this can be achieved quite elegantly using a list that visualizes its elements as labels (you should get that for free, but if not, it'd be trivial to change the control's ItemTemplate - sorry, I don't have any example immediately at hand).

Related

How to get the value of a variable to a string?

I am trying to add a item to my listView. The listView populates but I am getting this:
Systems.Collection.Generic.List'1[System.String]
This is the code I am trying to use:
foreach (SearchResult entry in result)
{
var members = GetGroupMemberList(entry.GetDirectoryEntry());
var item = members;
itmListItem = new ListViewItem((string)entry.Properties["sAMAccountName"][0]);
itmListItem.SubItems.Add(item.ToString());
lvwListView.Items.Add(itmListItem);
lvwListView.Refresh();
itmListItem = null;
}
Thanks
The problem you're running into is that item is not a string: it's a List<string>, so calling ToString() on it doesn't show you anything more meaningful than its type. Often people really want to get something like a comma-separated list of items to show, which could be accomplished by saying string.Join(", ", members).
But I'm reading the tea leaves here and thinking you probably really want each item in the members to show up as a sub-item in your list, which you could accomplish like this:
foreach (SearchResult entry in result)
{
var members = GetGroupMemberList(entry.GetDirectoryEntry());
foreach(var item in members)
{
var itmListItem = new ListViewItem((string)entry.Properties["sAMAccountName"][0]);
itmListItem.SubItems.Add(item.ToString());
lvwListView.Items.Add(itmListItem);
}
lvwListView.Refresh();
}
Note that I'm declaring itmListItem closer to where you actually use it, which makes it unnecessary to set it to null later. It's generally good practice to declare variables closer to their usage, and in as small as scope as possible.

Simplify double foreach instruction

I need to browse a word document and to retrieve some Text Boxes in order to modify them.
But I need to count them before, and I do think that what I wrote is really inefficient.
I'd like to know if it's possible to simplify the following:
foreach (Microsoft.Office.Interop.Word.HeaderFooter OHeader in documentOld.Sections[1].Headers)
{
foreach (Microsoft.Office.Interop.Word.Shape shape in OHeader.Shapes)
{
if (shape.Name.Contains("Text Box"))
{
listTextBox.Add(new KeyValuePair<string, string>(shape.Name.ToString(), shape.TextFrame.TextRange.Text.ToString()));
}
}
}
int count = listTextBox.Count();
I want to know how many elements which contain "Text Box" are in the Shapes.
I see two ways you can do this.
Using LINQ syntax:
var count = (
from OHeader in documentOld.Sections[1].Headers
from shape in OHeader.Shapes
where shape.Name.Contains("Text Box")).Count();
Or, using IEnumerable extension methods:
var count = documentOld.Sections[1].Headers
.SelectMany(h => h.Shapes)
.Count(s => s.Name.Contains("Text Box"));
Note that your version is inefficient in that it creates a list and the KeyValuePairs needlessly, given that you only want to count the number of shapes that match some condition. Other that that, nested foreach blocks are fine for performance, but may lack in readability versus the LINQ equivalents.
Also, please note that I have not tested the code above.
Keeping your code the same by using the foreach loops still all you need to do is have your count variable before the loops and increment it each time you find a match.
int count = 0;
foreach (Microsoft.Office.Interop.Word.HeaderFooter OHeader in documentOld.Sections[1].Headers)
{
foreach (Microsoft.Office.Interop.Word.Shape shape in OHeader.Shapes)
{
if (shape.Name.Contains("Text Box"))
{
++count;
}
}
}

How to rename value in a List without creating a new one?

I have a list of strings List<string> blobsToCopy
var newList = blobsToCopy.Select(GetDiskNameWithoutFolder);
private static string GetDiskNameWithoutFolder(string path) {...}
How to change all values in the blobsToCopy without creating a new IEnumerable<string>?
You don't use LINQ, just use a simple for loop and replace each item with its modified version.
for (var i = 0; i < blobsToCopy.Count; i++)
{
blobsToCopy[i] = GetDiskNameWithoutFolder(blobsToCopy[i]);
}
Unless I'm missing something obvious, what's wrong with a good old-fashion for loop?
for(var i=0; i < blobsToCopy.Count;i++)
{
// do whatever....
}
Well, strings are immutable, so you can't edit those directly. Instead you could edit your list with blobsToCopy[i]. This will keep your list intact and let you edit which string the element of the list points to.
Maybe you could use the ForEach linq implementation. Don't have a c# compiler available at the moment, so I can't test this.
list.ForEach(c => c = GetDiskNameWithoutFolder(c));

Using Linq how I have to add list items

IEnumerable<ReportFavorite> list = reportService.GetReportFavorites(userId);
ddlReportFavorite.Items.Add()
I don't know how to add the lists to the dropdown using Linq. Thanks.
You an use AddRange method:
var list = reportService.GetReportFavorites(userId);
ddlReportFavorite.Items.AddRange(list.ToArray());
Depending on the dropdown control you are using, either of these could work:
If it allows its Items to be set to an IEnumerabe<ReportFavourite>:
ddlReportFavorite.Items = reportService.GetReportFavorites(userId);
If Items implements the AddRange method:
ddlReportFavorite.Items.AddRange(reportService.GetReportFavorites(userId));
Or, if these fail
foreach(var reportFavourite in reportService.GetReportFavorites(userId))
ddlReportFavorite.Items.Add(reportFavourite);
Neither of these methods is really "using LINQ", because LINQ is not a good tool to do this. LINQ is meant to be side-effect free.
Edit:
Your comment suggests that you are using a System.Web.UI.WebControls.DropDownList. In this case, the Items collection only accepts instances ListItem, so you need to create these from your ReportFavourites. Try
foreach(var listItem in reportService.GetReportFavorites(userId)
.Select(r => new ListItem(r.Id, r.Name))
ddlReportFavorite.Items.Add(listItem);
Here, I assume the combo box should display ReportFavourite.Name and have a value of ReportFavourite.Id. Use your own properties, of course
Or if you've already checked the data's integrity in the method, you could just simply say:
ddlReportFavorite.Items.AddRange(reportService.GetReportFavorites(userId));
Previously I put as IEnumerable. Now I changed to IList. It is working fine now. Thanks to all.
int userId = workContext.CurrentUser.UserID;
var reportFavoriteList = reportService.GetReportFavorites(userId);
int count = reportFavoriteList.Count;
for (int i = 0; i < count; i++)
{
ddlReportFavorite.Items.Add(reportFavoriteList[i].FavoriteName);
}
Since ddlReprotFavorite is an UI control and itsItemsproperty represent a set of controls as well you can not add directly your business entities instead of use DataSource property which automatically create Items collection from the underlying business entities.
IEnumerable<ReportFavorite> list = reportService.GetReportFavorites(userId);
ddlReportFavorite.DataSource = list;
The IEnumerable<T> is extended by the method Union<T> which unions two IEnumerable<T>'s. This is the more pretty way, without casting it ToList().
var reportFavoriteList = reportService.GetReportFavorites(userId);
ddlReportFavorite.Items = ddlReportFavorite.Items.Union(reportFavoriteList);

Don't understand why the ForEach command isn't working

I am wanting to trim any white space off a collection of strings. I used the following code but it doesn't seem to work. Could anyone explain why?
result.ForEach(f => f = f.Trim());
This won't work because you are assigning a new string reference to a local variable. This is probably what you are looking for:
result = result.Select(f => f.Trim()).ToList();
You are re-assigning the argument variable inside the scope of the lambda. It's a collapsed form of:
foreach(string value in myList)
{
Lambda(value);
}
void Lambda(string input)
{
input = input.Trim();
}
The simplest way would probably be to use a projection:
myList = myList.Select(str => str.Trim()).ToList();
foreach doesn't give you write access to the underlying collection, it only iterates through it, which means your change isn't stored back into the collection.
You can do two things:
Produce a new collection
var newResult = result.Select(f => f.Trim()).ToList();
Use a normal for-loop and change the original collection
for (int index = 0; index < result.Count; index++)
result[index] = result[index].Trim();

Categories

Resources