1
\$\begingroup\$

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; }
        }

    }
\$\endgroup\$

3 Answers 3

1
\$\begingroup\$

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; }
\$\endgroup\$
1
  • \$\begingroup\$ Since both Drinks and Bread are List<Product>, there is no reason to use the non-generic Array here. Or to call ToArray(). (The fact that the original code does that is no excuse, I think code review should catch things like that too.) \$\endgroup\$
    – svick
    Commented Aug 20, 2013 at 22:22
0
\$\begingroup\$

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);
  }

}
\$\endgroup\$
2
  • \$\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\$ Commented 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
    Commented Aug 21, 2013 at 6:42
0
\$\begingroup\$

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);

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.