Search code examples
c#formsoop

Items.Add cannot be used because it is not the "DataSource" C# + WindowsForm


I am trying to add an item to aircraftList ListBox and be able to click on it and on a detailsList TextBox display all information per item selected. However, I am using BindingList<AircraftDetails> Details = new BindingList<AircraftDetails>(); and AircraftClass which contains the following method:

public override string ToString()
    {
        List<string> builder = new List<string>();
        builder.add("something here like a variable");

which wil return all details to the detailsList textBox.

Now, the issue is that when I tried to do something like aircraftList.Items.Add("Test") it will show a error message showing this enter image description here

I am at a loss for what to do, however I will provide the repository of my code that is hosted on gitHub so that you can better comprehend it. REPOSITORY


Solution

  • Thank you for posting your repository in support of your question. That made it easy to reproduce the issue. Making a minor change to your addaircraftButton_Click "should" do the trick.

    public void addaircraftButton_Click(object sender, EventArgs e)
    {
        FlightSetup addplane = new FlightSetup();
        AircraftDetails aircraftDetails = new AircraftDetails();
        using (addplane)
        {
            DialogResult result = addplane.ShowDialog();
    
            planeModel = addplane.planeModel_textbox.Text;
            airline = addplane.airline_textbox.Text;
            fuelG = double.Parse(addplane.fuel_textbox.Text);
            bag1 = int.Parse(addplane.carryonTextBox.Text);
            bag2 = int.Parse(addplane.checkedBagsTextBox.Text);
    
            object o = new AircraftDetails
            {
                AircraftModel = planeModel,
                Airline = airline,
                Fuel = fuelG, //TESTING
                OnBoardBags = bag1,
                CheckedBags = bag2,
                
                // Don't forget to assign TailNumber!
            };
            detailsList.Text = o.ToString();
        }
    
        //aircraftList.Items.Add(planeModel); // not working right here <--
    
        // Do this instead!
        Details.Add(aircraftDetails);
    }
    

    Obviously, you were very close to having the right code. The trick is that once you bind to a DataSource, you should work directly with that data Details.Add(aircraftDetails) and should no longer attempt to manipulate the UI control directly.


    Optimized Solution

    Consider that you could make FlightSetup responsible for creating a new AircraftDetails. If you remove all the event handlers that aren't doing anything, you get something like this:

    public partial class FlightSetup : Form
    {
        public FlightSetup()
        {
            InitializeComponent();
        }
        private void buttonFinish_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.OK;
        }
        public AircraftDetails GetAircraftDetails()
        {
            var aircraftDetail = new AircraftDetails
            {
                // Please look into int.TryParse to make this more fault-tolerant.
                TailNumber = int.Parse(tailno_textbox.Text),
                AircraftModel = planeModel_textbox.Text,
                Airline = airline_textbox.Text,
                Fuel = double.Parse(fuel_textbox.Text),
                OnBoardBags = int.Parse(carryonTextBox.Text),
                CheckedBags = int.Parse(checkedBagsTextBox.Text),
            };
            return aircraftDetail;
        }
    }
    

    Now, back in the main form you have a squeaky-clean method:

    public void addaircraftButton_Click(object sender, EventArgs e)
    {
        using (FlightSetup addplane = new FlightSetup())
        {
            DialogResult result = addplane.ShowDialog();
    
            if(result == DialogResult.OK)
            {
                AircraftDetails aircraftDetails = addplane.GetAircraftDetails();
                Details.Add(aircraftDetails);
                detailsList.Text = aircraftDetails.ToString();
                aircraftList.SelectedItem = aircraftDetails;
            }
        }
    }
    

    When your code is run after making these changes, here is the result:

    after adding