Reputation: 429
I have this model:
class Car
{
string CrewNickname { get; set; }
Líst<string> RacersNames { get; set; }
}
class StartingField
{
List<Car> Cars { get; set; }
}
What I need is to display cars in one ListBox and when I click on any car, to display names of its racers in the second ListBox.
I also need to be able to add/remove cars and add/remove/edit racers.
I haven't found any suitable tutorial or question, but I think this must be possible to create.
Upvotes: 1
Views: 275
Reputation: 32223
You can do something like this:
RacersNames
CarID
Property is there just to show the use of ValueMember
)BindingSource bsCars = null;
BindingSource bsRacers = null;
StartingField startingField = null;
public class Car
{
public Car(string carName, int carID) { CarName = carName; CarID = carID; }
public string CarName { get; }
public int CarID { get; }
public List<string> RacersNames { get; set; } = new List<string>();
}
public class StartingField
{
public List<Car> Cars { get; } = new List<Car>();
}
Then initialize the source of data and set the DataSource of the BindingSource objects and the ListBoxes.
Since the second BindingSource is linked to the RacersNames
property of the first BindingSource, when you select a car name in the first ListBox, the second BindingSource will update its content and, as a consequence, the ListBox bound to it will show the list of RacersNames
related to the new selection.
Elements can be added or removed from both lists.
You can add this code to the Load
event (or OnLoad()
override) of a Form.
protected override void OnLoad(EventArgs e)
{
startingField = new StartingField();
var c1 = new Car("Car1", 1) { RacersNames = { "Racer1", "Racer2", "Racer3" } };
var c2 = new Car("Car2", 2) { RacersNames = { "Racer4", "Racer5", "Racer6" } };
var c3 = new Car("Car3", 3) { RacersNames = { "Racer7", "Racer8", "Racer9" } };
startingField.Cars.AddRange(new[] { c1, c2, c3});
bsCars = new BindingSource(startingField.Cars, "");
bsRacers = new BindingSource(bsCars, "RacersNames");
lstCars.DisplayMember = "CarName";
lstCars.ValueMember = "CarID";
lstCars.DataSource = bsCars;
lstRacers.DataSource = bsRacers;
}
To add or remove Car
objects, or add/remove elements from the current RacersNames
list, use the linked BindingSources.
You can add/remove elements from the underlying BindingList (the list created internally).
See the animation to determine what Buttons this code maps to
private void btnAddCar_Click(object sender, EventArgs e)
{
var newCar = startingField.Cars.Count + 1;
bsCars.Add(new Car($"Car{newCar}", newCar)
{
RacersNames = { "Racer10", "Racer11", "Racer12" }
});
}
private void btnAddRider_Click(object sender, EventArgs e)
{
bsRacers.Add("New Rider");
}
private void btnRemoveRider_Click(object sender, EventArgs e)
{
if (lstRacers.SelectedIndex < 0) return;
bsRacers.Remove(lstRacers.GetItemText(lstRacers.SelectedItem));
}
This is how it works:
Upvotes: 2
Reputation: 41
You should use the OnSelectedIndex method for the first listbox, that raises the SelectedValueChanged event. Then populate the second listbox based on the selected index of the first listbox.
Upvotes: 0