Okay so the break down. I have a simple application. You can create a new vehicle, either a car, sports car, truck, or minivan. That object is then loaded into a listbox. Each one has 4 methods that display the message box (Start, Drive, Park, Wash). So if I create a 1992 Toyota Corolla, it's added into the listbox, but I'm trying to figure out a way to be able to select the Corolla in the listbox and then click a button to call the method and display the message box. Any ideas how I would go about this? I've tried just about everything I can think of, and Google and Bing were of no help at all.

Recommended Answers

All 19 Replies

In the design tab, double click the listbox. That'll start a sub routine stub for the SelectedIndexChanged event. When you make a selection in the listbox this event will fire and you can display your messagebox there. For instance:

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            MessageBox.Show(listBox1.Text);
        }

That was among the first things I tried. Perhaps I should clarify a little more. The Class that is responsible for all the objects is located in a seperate .cs file, and I'm trying to determine how to call those specific methods located in the class file, not just show what's in the listbox via a Message Box. I'm including an example of the class code to clarify. I'm wanting to call the 4 methods at the bottom of the page on another form (where the list box and buttons are).

public class VehicleClass
    {
        // Abstract Class
        public abstract class Vehicle
        {
            // Abstract Property
            public int Year
            {
                get;
                set;
            }

            // Abstract Method
            public virtual void StartVehicle()
            {

            }
        }

        // Base Class
        public class Automobile : Vehicle
        {
            // Fields
            public int _year;
            public string _make;
            public string _model;
            public string _color;

            // Default Constructor
            public Automobile()
            {

            }

            // Constructor
            public Automobile(int year, string make, string model, string color)
            {
                _year = year;
                _make = make;
                _model = model;
                _color = color;
            }

            // Year Property
            public new int Year
            {
                get { return _year; }
                set { _year = value; }
            }

            // Make Property
            public string Make
            {
                get { return _make; }
                set { _make = value; }
            }

            // Model Property
            public string Model
            {
                get { return _model; }
                set { _model = value; }
            }

            // Color Property
            public string Color
            {
                get { return _color; }
                set { _color = value; }
            }

            // Override StartVehicle Method
            public override void StartVehicle()
            {
                MessageBox.Show("Automobile Started.");
            }

            // Drive Method
            public void Drive()
            {
                MessageBox.Show("Went for a nice drive in the Automobile.");
            }

            // Park Method
            public void Park()
            {
                MessageBox.Show("Parked the Automobile in the driveway");
            }

            // Wash Method
            public void Wash()
            {
                MessageBox.Show("Washed the Automobile. Looks Great!");
            }
        }

Use GetSelectedItem to get the object, then just call the methods.

I think that you need to make things static so that they can be shared. But I'm not sure how that'll work with the abstract, override, and virtual modifiers you've got.

They don't need to be static. Rarely do things need to be static.

Made some changes to your code. Not sure if they'll fit with what you'll need in the end, but you can access all of automobile's properties and methods from your form, just use VehicleClass.Automobile.

    public class VehicleClass
    {
        // Abstract Class
        public abstract class Vehicle
        {
            // Abstract Property
            public  int Year
            {
                get;
                set;
            }
            // Abstract Method
            public virtual void StartVehicle()
            {
            }
        }
        // Base Class
        public class Automobile : Vehicle
        {
            // Fields
            public static int _year;
            public static string _make;
            public static string _model;
            public static string _color;
            // Default Constructor
            public  Automobile()
            {
            }
            // Constructor
            public  Automobile(int year, string make, string model, string color)
            {
                _year = year;
                _make = make;
                _model = model;
                _color = color;
            }
            // Year Property
            public new int Year
            {
                get { return _year; }
                set { _year = value; }
            }
            // Make Property
            public  string Make
            {
                get { return _make; }
                set { _make = value; }
            }
            // Model Property
            public string Model
            {
                get { return _model; }
                set { _model = value; }
            }
            // Color Property
            public string Color
            {
                get { return _color; }
                set { _color = value; }
            }
            // Override StartVehicle Method
            public static new void StartVehicle()
            {
                MessageBox.Show("Automobile Started.");
            }
            // Drive Method
            public static void Drive()
            {
                MessageBox.Show("Went for a nice drive in the Automobile.");
            }
            // Park Method
            public static void Park()
            {
                MessageBox.Show("Parked the Automobile in the driveway");
            }
            // Wash Method
            public static void Wash()
            {
                MessageBox.Show("Washed the Automobile. Looks Great!");
            }


        }
    }

Hope this helps.

It won't help. Remove the static from the class because that will make all the cars the exact same. You want different cars!

Using your (tinstaafl) example way up top, this is how you'd code the event:

private void SelectedIndexChanged(object sender, EventArgs e) {
    ListBox lb = sender as ListBox;

    Vehicle v = (Vehicle)lb.SelectedItem;

    v.Drive(); 
}

Casting the sender into a ListBox gets you the listbox object that triggered the event. SelectedItem is the one they selected (since it returns Object we cast it into the Vehicle type). Then we can call all the methods we want on that instance.

With the class being in a different file, without the static, none of the properties or methods were visible to the form. If you use a variable of VehicleClase.Automobile type and make it an array you can have any number of different vehicles, with the static in the code. They don't have to all be the same they can be different. You can add, delete, to/from the listbox, view any vehicle with ease. If there is another way, to access the the properties and methods, of a class, from a different file it would be nice to know what it is, rather than just hearing that it's wrong.

Being in a different file has no affect an accessibility. The class is Public, the properties are public. They are accessible from anywhere.

Think about it for a bit, all the form controls are in a different file than the one you use to create your forms, but you can still access them. Different files just makes it easier to organize your project.

And you seem to be confused on what static does. A static property shares its value with all the classes, and it's only accessible through the class, not instances of the class.

I can see what you are both saying, but what I posted is just a small fragment of what I actually have for the entire VehicleClass file. From Automobile, I have three other classes that are derived from it. Car, Truck, and Minivan. Another class, Sports Car, is derived from car.

The ultimate problem I'm running into is not being able to say "element 0 in the listbox is a car, so I'll call the Car.StartVehicle() to display the appopriate message box" or "element 1 in the listbox is a truck, so I'll call the Truck.StartVehicle() to display the message box for it."

I've been working on this throughout the night. I've had some luck but my brain is fried.

What I was hoping to be able to do is show "1992 Toyota Corolla White 2 Door" in the listbox (Which I can, no problem there, it's working) and then when I select it, be able to call the Car.StartMethod when clicking on the button Start Vehicle.

the code I was trying to use in the SelectedIndexChanged event was like this
(ListBox SelectedIndexChanged)

 if (lsbCars.SelectedIndex is VehicleClass.Car)
{    
    isCar = true;
    isSportsCar = False;
    isTruck = False;
    isMiniVan = False;
}

Hoping that when I clicked the button event
(button Start Vehicle)

 if (isCar = True)
 {
    Car.StartVehicle();
 }

But Intellisense hates that because VehicleClass.Car is a type. I have tried adding a string property to the classes to hold what they are (So the Corolla I mentioned earlier now has a _type property that says "Car" but I can't find a way to access it once I place it inside of the listbox. Really frustrating lol.

@ Momerath - I noticed earlier you said to use GetSelectedItem and I wasn't able to find anything on that in the IDE (Microsoft Visual Studio) or Google. Also, I will try your other example (tinstaafl's modified event) after I get some rest. I noticed you said Cast it into the listbox, but I've never really had to use cast yet. I've just wasted a bunch of time trying to get this to work without anyone's help. Not trying to ask people to do the work for me lol.

@Tinstaafl - I had already tried Static and that crashed and burned. It worked for letting me see everything to lay it out, but not when it came to testing it. Nothing I ever decide to do is easy I guess. I did a poor job explaining it earlier, I apologize.

Even after getting some rest, I'm still a little confused about the Example you gave. Would that work even for multiple vehicles in the listbox?

Sorry about my earlier missteps, still learning myself :). Try this in the selectedindexchanged event:

            ListBox lb = sender as ListBox;
            VehicleClass.Automobile v = (VehicleClass.Automobile)lb.SelectedItem;
            v.Drive();

I used .drive() but you can access any of the properties and methods,, assuming the items in your listbox can be cast as type vehicleclass.automobile. That part I'm a little fussy on myself.

Well actually, I use VehicleClass.Car.

See, I'm having to use Abstraction, Inheritance, and Polymorphism. So Vehicle is a good way to describe just about anything with a motor and wheels. But I never need an instance of it. Next, Automobile will cover most public road things. So Vehicle->Automobile, which is a base for either Car, Truck, or Minivan. Sports Car is derived from Car, because it is a vehicle, it is an automobile, and it is a kind of Car, but not a kind of Truck or Minivan. I'm down to just two issues. Serialization, which I'm covering on anthor Forum, and this Listbox issue which I've come here for. Those are the last two hangups on this project. I'm making steps, and revised my code since I was posting last night. I'm going to try this out and see if it works.

Everything looks fine on the surface in the IDE, but once I get into the example above I get this.

Exception_Error1Exception_Details

Passing the class into the listbox seems to be complicated. It might be easier to write some code that parses the string from the listbox and finds the vehicle based on that

Nope... It's actually REALLY simple. Here's how to do it.

if (MyVehicles[lsbAutomobiles.SelectedIndex]._type == "Car")
            {
                isCar = true;
                btnStartVehicle.Enabled = true;
                btnWashVehicle.Enabled = true;
                btnDriveVehicle.Enabled = false;
                btnParkVehicle.Enabled = false;
                isSportsCar = false;
                isTruck = false;
                isMiniVan = false;
            }

Can't believe it was that easy. And that I figured it out on my own.

Now on to solve the Serialization Issue!! :D

Glad you figured it out.

An upvote for the newbie would be greatly appreciated :D

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.