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 ofValueMember
) - 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:
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
How to Prevent a SQL Injection Escaping Strings
How to Pass Data from Mainwindow to a User Control That's Inside the Mainwindow
What's the Difference Between Returning Void and Returning a Task
Does Using Tasks (Tpl) Library Make an Application Multithreaded
Mvvm Light 5.0: How to Use the Navigation Service
Convert System.Drawing.Icon to System.Media.Imagesource
How to Use Dependency Injection with an Attribute
How to Find System.Web.Helpers, System.Web.Webpages, and System.Web.Razor
How to Downgrade from Visual Studio 2012 Project to Visual Studio 2008
How to Handle Null or Optional Dll Struct Parameters
Why Use Try {} Finally {} with an Empty Try Block
Get File Name from Uri String in C#
Linq Expression to Return Property Value
How to Get the Closest Number from a List<Int> with Linq
What Is the Simplest C# Function to Parse a JSON String into an Object