I'm a beginner in C# and am doing a simple programming exercise. I would like to put the Item.price
and Item.Name
into Listbox2
.
Is it possible to put the array name into a variable and iterate with a foreach
loop? This is to avoid a very long if
, switch
, or while
loop. It could also be useful in the future if I have 40 lists.
Example
Array variable = Drinks;
foreach(Product item in variable)
{
listBox2.Items.Add(item.ProductName + item.Price);
}
PS: I've already tried using a temporary List, where I put the Drinks
into the list and call it by Product.Name
and/or Product.price
.
Could it also be more efficient? I'm very open to new ideas or approaches on how I should make my code shorter and more efficient.
public partial class Form1 : Form
{
List<Product> Drinks = new List<Product>() { new Product("Coca Cola", 1.2F), new Product("Fanta", 2.0F), new Product("Sprite", 1.5F) };
List<Product> Bread = new List<Product>() { new Product("Brown Bread", 1.2F), new Product("White Bread", 2.0F), new Product("Some otherBread", 1.5F) };
public Form1()
{
InitializeComponent();
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
listBox1.Items.Clear();
// instead of 40 if loops or a while loop is it possible to change the List Name with a variable and use only 1 foreach loop as the example i showed above?
if (comboBox1.Items.IndexOf(comboBox1.SelectedItem) == 0)
{
foreach (Product item in Drinks)
{
listBox1.Items.Add(item.ProductName);
}
}
else
{
foreach (Product item in Bread)
{
listBox1.Items.Add(item.ProductName);
}
}
}
private void listBox1_MouseDoubleClick(object sender, MouseEventArgs e)
{
// do something here
}
}
public class Product
{
private string productName;
private float price;
public Product(string productName, float price)
{
this.ProductName = productName;
this.Price = price;
}
public string ProductName
{
get { return productName; }
set { productName = value; }
}
public float Price
{
get { return price; }
set { price = value; }
}
}
3 Answers 3
Is it possible to put the array name into a variable and iterate by a foreach loop?
YES.
Array ProductItems = Drinks.ToArray();
foreach(Product item in ProductItems)
{
Console.WriteLine(item.ProductName);
}
Now about your second question, (it's unclear what's the significance of the first question)...
If there are many products and user selects one from the combobox1
how to update the product details in listbox1
? (is this your question?)
Answer : Make a Dictionary of combobox1
index and ProductList
. Iterate over the combobox1
list and map the indexes with the ProductList
. This may help.
Dictionary ProductDict = new Dictionary<int, List<Product>>();
Then after SelectedIndexChanged
event is fired get the ProductList
corresponding with combobox1
index. Then iterate over the list and add the details it in listbox.
General Review
Since productName
and price
is trivial make them auto-implemented properties
public string ProductName { get; set; }
-
\$\begingroup\$ Since both
Drinks
andBread
areList<Product>
, there is no reason to use the non-genericArray
here. Or to callToArray()
. (The fact that the original code does that is no excuse, I think code review should catch things like that too.) \$\endgroup\$svick– svick2013年08月20日 22:22:15 +00:00Commented Aug 20, 2013 at 22:22
What you are looking for is a variable that kan hold the reference to one of the lists, then you can loop through whatever that variable points to.
You can use a switch
to select which of the lists you are referring to. Example:
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) {
listBox1.Items.Clear();
List<Product> products;
switch (comboBox1.Items.IndexOf(comboBox1.SelectedItem)) {
case 0: products = Drinks; break;
case 1: products = Meat; break;
case 2: products = Cheeses; break;
case 3: products = Sauces; break;
default: products = Bread; break;
}
foreach (Product item in products) {
listBox1.Items.Add(item.ProductName);
}
}
-
\$\begingroup\$ But OP states that he doesn't want a long switch-case statement which is true if there are like 100 items in the
combobox1
list. \$\endgroup\$Anirban Nag 'tintinmj'– Anirban Nag 'tintinmj'2013年08月21日 05:36:29 +00:00Commented Aug 21, 2013 at 5:36 -
\$\begingroup\$ @tintinmj: The OP has a switch with a loop for each case, which would be a very long switch with many cases, but assigning a reference in each case makes it a reasonably short switch even with many cases. It's not longer than populating a dictionary with the options for example. \$\endgroup\$Guffa– Guffa2013年08月21日 06:42:41 +00:00Commented Aug 21, 2013 at 6:42
You can add new abstraction, instead of using a bunch of lists. For example:
class Category
{
public string Name { get; private set; } //or other Id. Some Enum probably?
public IList<Product> Products { get; private set; }
public Category(string name)
{
Name = name;
Products = new List<Products>();
}
public override string ToString()
{
return Name;
}
}
Then you can simply populate your comboBox1
with Category
objects, and handle selection event like this:
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
listBox1.Items.Clear();
var category = (Category)comboBox1.SelectedItem;
if (category == null) return;
//cant you AddRange or assign? I'm not very familiar with winforms
foreach (Product item in category.Products)
{
listBox1.Items.Add(item.ProductName);
}
}
As for your first question: you can override ToString
method of your Product
class to return Name+Price the same way it is done for Category
. Then you can simply call listBox1.Items.Add(item);