Click here to Skip to main content
15,891,883 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Afternoon all,

I have a little project that represents a petrol station. I have a user control that represents a petrol-pump. These can be added and removed dependant on how many are required.

In my user control I have a combo-box that holds the fuel choices {Diesel, Premium, Unleaded} for example.

The problem I have is that when I select a fuel in one instance of a user control, it also changes the selection in all other instances. I thought they would be completely independant of one another?

How can I achieve this? I want to have one pump running Diesel, whilst the others can be running Unleaded or Premium.

C#
private void btnAddPump_Click(object sender, EventArgs e)
{
    //creates a petrolpump control instance and assigns a pump identifier

    //tlpPumpControlHolder.Controls.Add(new PetrolPump());
    PetrolPump pumpInstance = new PetrolPump(_pumpIndex);
    tlpPumpControlHolder.Controls.Add(pumpInstance);
    //increment unique identifier
    _pumpIndex++;

    //needs calling to update fuel list for new pumps
    UpdatePumpsWithFuels();

}


the UpdatePumpsWithFuels(); code:
C#
//once the fuels have been updated, then a method is required to send this new information to all the pumps
        private void UpdatePumpsWithFuels()
        {
            //iterate through the controls in tlpPumpControlHolder (should all be PetrolPumps)
            foreach (Control _control in tlpPumpControlHolder.Controls)
            {
                //incase not all PetrolPump controls
                PetrolPump _pump = _control as PetrolPump;

                if (_pump != null)
                    _pump.FuelList = _fuelList;

            }
        }



Although I never called this when created the controls via the designer.

/also the Fuel Class, _fuelList is just a List<> if these

C#
public class Fuel
{
    #region Private Members
    private string _fuelName;
    private double _fuelCost;
    #endregion
    //Make private members accessible

    #region Accessors to Private Members
    public string FuelName
    {
        get
        {
            return _fuelName;
        }
        set
        {
            _fuelName = value;
        }
    }

    public double FuelCost
    {
        get { return _fuelCost; }
        set { _fuelCost = value; }
    }

    #endregion
    #region Constructors

    public Fuel()
    {
    }

    public Fuel(string FuelName, double FuelCost)
    {
        _fuelName = FuelName;
        _fuelCost = FuelCost;
    }

    #endregion

    //this is used so that the combobox displays the text value of FuelName, rather than the object
    //you can see this by simply commenting this out
    public override string ToString()
    {
        return _fuelName;
    }
}


Kind regards,

Mike.


Anyone??
Posted
Updated 5-Jun-10 9:48am
v7
Comments
Henry Minute 4-Jun-10 11:52am    
I see nothing that jumps out at me as being wrong with that code. So the only question left is what is the code in UpdatePumpsWithFuels(). If you would add that code to your question I think we would be able to help more.
Jibrohni 4-Jun-10 15:44pm    
code now included - thanks
Jibrohni 5-Jun-10 7:53am    
Anyone?

OK! Problem resolved. Not solved, you'll note, as I'm not sure why your code was misbehaving. However, if you make these changes it works as desired.

First your btnAddPump_Click method. At the end you Update all existing pumps, rather than just setting the fuel for the new one. This will slow your app down considerably and I would therefore suggest the following changes.

C#
private void btnAddPump_Click(object sender, EventArgs e)
{
  //creates a petrolpump control instance and assigns a pump identifier
  //tlpPumpControlHolder.Controls.Add(new PetrolPump());
  PetrolPump pumpInstance = new PetrolPump(_pumpIndex);
  pumpInstance.FuelList = NewFuelList();  //<========= New line NewFuelList() below.
  tlpPumpControlHolder.Controls.Add(pumpInstance);
  //increment unique identifier
  _pumpIndex++;
}


If you still want to call UpdatePumpsWithFuels() you can do it that way and ignore this suggestion (but see modified UpdatePumpsWithFuels() later).

Now the NewFuelList() method.

C#
private List<Fuel> NewFuelList()
{
    List<Fuel> result = new List<Fuel>();
foreach (Fuel fuel in _fuelList)
    {
        result.Add(new Fuel()
        {
            FuelName = fuel.FuelName,
            FuelCost = fuel.FuelCost
        });
    }

    return result;
}


The modified UpdatePumpsWithFuels() method.

C#
//once the fuels have been updated, then a method is required to send this new information to all the pumps
private void UpdatePumpsWithFuels()
{
  //iterate through the controls in tlpPumpControlHolder (should all be PetrolPumps)
  foreach (Control _control in tlpPumpControlHolder.Controls)
  {
      //incase not all PetrolPump controls
      PetrolPump _pump = _control as PetrolPump;
      if (_pump != null)
          _pump.FuelList = NewFuelList();
  }
}


I have not yet worked out why the old code misbehaved but if I do, I will let you know. For now this works.
 
Share this answer
 
v2
I have just sat down for an infusion of stimulants after my previous post and as I did so the answer came to me. So my coffee is getting cold while I type this.

In your PetrolPump when you set the FuelList I believe you set the DataSource for your ComboBox to the new FuelList. Since all the DataSources point to the same actual list (_fuelList) they all update their position when the RowIndex for one changes. This is the designed behaviour for DataBinding.

I hope that you can understand this.

Good luck anyway! :)
 
Share this answer
 
Comments
Jibrohni 6-Jun-10 6:48am    
I do understand that - thank you so much for your time. It works wonderfully now.

It's sometimes the simple things that frustrate me the most - although I shall probably take that comment back, as my next port of call is Delegates and Events...

Thanks again!
That's rather strange. All I can think of is that each of your user controls references the same combo box, perhaps you have marked it as static?.
 
Share this answer
 
Comments
Jibrohni 4-Jun-10 11:22am    
I haven't changed anything - When I create a new Pump control I add it to a tablelayoutpanel control list. But it's as though the controls are all one and the same??
Are you adding these controls dynamically, or at design time?
 
Share this answer
 
Comments
Jibrohni 4-Jun-10 11:25am    
dynamically
Jibrohni 4-Jun-10 11:26am    
private void btnAddPump_Click(object sender, EventArgs e)
{
//creates a petrolpump control instance and assigns a pump identifier

//works without parameters
//tlpPumpControlHolder.Controls.Add(new PetrolPump());
PetrolPump pumpInstance = new PetrolPump(_pumpIndex);
tlpPumpControlHolder.Controls.Add(pumpInstance);
//increment unique identifier
_pumpIndex++;

//needs calling to update fuel list for new pumps
UpdatePumpsWithFuels();

}
Please edit your original question to show the code that you use to add a pump.

Does it behave the same if you add them in the designer?
 
Share this answer
 
Comments
Jibrohni 4-Jun-10 11:32am    
exactly the same - I added 4 on formload event and it shows the same problem
I have just built a small test project using the code you have posted and much to my amazement it does what you say.

I'm looking at it now and will get back to you.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900