Binding Listbox to List<Object> in Winforms

Binding Listbox to Listobject in WinForms

You're looking for the DataSource property:

List<SomeType> someList = ...;
myListBox.DataSource = someList;

You should also set the DisplayMember property to the name of a property in the object that you want the listbox to display. If you don't, it will call ToString().

Bind Winforms ListBox collection to Listobject

I found that List<T> will not allow updating of a ListBox when the bound list is modified.
In order to get this to work you need to use BindingList<T>

BindingList<CustomerData> MyData = new BindingList<CustomerData>();

MyListBox.DataSource = MyData;
MyListBox.DisplayMember = "Name";

MyData.Add(new CustomerData(){ Name = "Jimmy" } ); //<-- This causes the ListBox to update with the new entry Jimmy.

Bind ListDouble to WinForms-Listbox

When I update the values, nothing appears?!

_measuredValues.Add(numBuffer);

In order to allow UI to reflect the data source modifications, the data source must provide some sort of a change notification. WinForms list data binding infrastructure uses ListChanged event of the IBindingList Interface. There is a standard provided BindingList<T> class which can be used instead of List<T> to get the desired behavior. All you need is changing this line

List<double> _measuredValues = new List<double>();

to

BindingList<double> _measuredValues = new BindingList<double>();

Another reason might be that the upper line of code is within another thread. But I think this should not be the problem.

That's not good. You must make sure you don't do that because ListChanged event is expected to be raised on the UI thread.

Binding (and refreshing) a ListT to a ListBox

If you import the System.ComponentModel namespace, then you can use a binding list of string, which will automatically raise events on changes:

private void FillItems()
{
allItems = GetAllItems();
availableItems = new BindingList<string>(allItems);
selectedItems = new BindingList<string>();

itemsListBox.DataSource = availableItems;
selectedItemsListBox.DataSource = selectedItems;
}

private void addItemButton_Click(object sender, EventArgs e)
{
object itemsToAdd = itemsListBox.SelectedItems;
foreach (string item in itemsToAdd) {
availableItems.Remove(item);
selectedItems.Add(item);
}
}

This link has further information on the difference between observable collections and binding lists. difference between ObservableCollection and BindingList

How to bind a ListBox to a property of type List on an object?

You can use a linked BindingSource. A full example is below, but the only interesting bit is:

        BindingSource outer = new BindingSource(customers, ""),
inner = new BindingSource(outer, "Orders");

here's the code:

using System;
using System.Collections.Generic;
using System.Windows.Forms;
class Order
{
public string OrderRef { get; set; }
public override string ToString() {
return OrderRef;
}
}
class Customer
{
public string Name {get;set;}
public Customer() { Orders = new List<Order>(); }
public List<Order> Orders { get; private set; }
}
static class Program
{
[STAThread]
static void Main()
{
List<Customer> customers = new List<Customer> {
new Customer {Name = "Fred", Orders = {
new Order { OrderRef = "ab112"},
new Order { OrderRef = "ab113"}
}},
new Customer {Name = "Barney", Orders = {
new Order { OrderRef = "ab114"}
}},
};
BindingSource outer = new BindingSource(customers, ""),
inner = new BindingSource(outer, "Orders");
Application.Run(new Form
{
Controls =
{
new DataGridView {
Dock = DockStyle.Fill,
DataSource = outer},
new ListBox {
Dock = DockStyle.Right,
DataSource = inner
}
}
});
}
}

Bind the SelectedItem of a ListBox to another ListBox

You can do something like this:

  • Use two BindingSource objects to link each Car in the list to its list of RacersNames
  • Add a Property used to show each Car name in the first ListBox (the CarID Property is there just to show the use of ValueMember)
  • You need public Properties, of course.


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:

BindingSource Linked ListBoxES

Winforms Binding to ListBox

I think the problem is with your SetBinding method where you are making a new binding list, which means you aren't binding to the list in the Manager object anymore.

Try just passing the current BindingList to the datasource:

public void SetBinding(BindingList<string> messages)
{
// BindingList<string> toBind = new BindingList<string>(messages);
lbMessages.DataSource = messages;
}

c# winforms binding the properties of a ListBox SelectedItem

You don't need to use events, it's enough to use data binding:

missionsListBox.DataSource = bindingList;
missionsListBox.DisplayMember = "Name";
isStartedCheckBox.DataBindings.Add("Checked", bindingList, "IsStarted");
isCompletedCheckBox.DataBindings.Add("Checked", bindingList, "IsCompleted")

This way, the ListBox will act as an index for mission objects and it shows a list of missions. When you select an item, it shows values of IsStarted and IsCompleted in corresponding check box controls and you can change those values for selected item using check boxes.



Related Topics



Leave a reply



Submit