Reputation: 3515
Form has one Combobox and one ListBox. When the "Add" button is clicked, I want to add the selected item from the ComboBox to the ListBox.
public partial class MyForm:Form
{
List<MyData> data = new List<MyData>();
private void ShowData()
{
listBox1.DataSource = data;
listBox1.DisplayMember = "Name";
listBox1.ValueMember = "Id";
}
private void buttonAddData_Click(object sender, EventArgs e)
{
var selection = (MyData)comboBox1.SelectedItem;
data.Add(selection);
ShowData();
}
}
With this example, the selected item is replaced with the new selection inside ListBox. I need to add the item to the list.
What is wrong with my code?
Upvotes: 58
Views: 117655
Reputation: 984
refreshing also works via
listbox.ItemsSource = null;
listbox.ItemsSource = data;
Upvotes: 0
Reputation: 11
Maybe this solution has not the better performance, but after many tries and a few hours it was what it worked for me:
This line was executed on the form constructor:
listBox1.DataSource = myData;
This lines were executed after the information was modified:
listBox1.DataSource = new List<Movil>();
listBox1.DataSource = myData;
Hope it helps!
Upvotes: 0
Reputation: 2524
The listbox didn't detect that you have changed the DataSource
. It will only refresh when Datasource
has changed, so set DataSource
to null first:
listBox1.DataSource = null;
listBox1.DataSource = data;
You could also clear the items then set the DataSource again:
listBox1.Items.Clear();
listBox1.DataSource = data;
Upvotes: 20
Reputation: 5785
listbox1.DataSource
property looks for value changes but by assigning the same list all the time the value won't really change.
You can use a BindingList<T>
, instead of your List<T>
, to automatically recognize new items added. Your ShowData() method must be called once at startup.
public partial class MyForm:Form
{
public MyForm(){
InitializeComponent();
ShowData();
}
BindingList<MyData> data = new BindingList<MyData>();
private void ShowData()
{
listBox1.DataSource = data;
listBox1.DisplayMember = "Name";
listBox1.ValueMember = "Id";
}
private void buttonAddData_Click(object sender, EventArgs e)
{
var selection = (MyData)comboBox1.SelectedItem;
data.Add(selection);
}
}
Upvotes: 87
Reputation: 1566
Call ShowData()
when the form initializes to populate your listbox on initialization
public Department()
{
InitializeComponent();
ShowData();
}
ShowData()
Method, where BindingSource
, DisplayMember
and ValueMember
are set
private void ShowData()
{
using (var uow = new UnitOfWork(new SellContext()))
{
listBox1.DataSource = uow.Departments.GetAll().ToList();
listBox1.DisplayMember = "DepartmentName";
listBox1.ValueMember = "DepartmentId";
//listBox1.Invalidate();
}
}
In the implementation below when a department is deleted from database the listbox refreshes with the current collection
private void button1_Click(object sender, EventArgs e)
{
try {
using (var uow = new UnitOfWork(new SellContext()))
{
int count = uow.Departments.FindDepartmentByName(txtDeptName.Text.ToString());
if (count>0)
{
MessageBox.Show("This Department Already Exists", "SellRight", MessageBoxButtons.OK, MessageBoxIcon.Hand);
}
else
{
department dept = new department();
dept.DepartmentName = txtDeptName.Text.ToString();
uow.Departments.Create(dept);
if (uow.Complete() > 0)
{
MessageBox.Show("New Department Created", "SellRight", MessageBoxButtons.OK, MessageBoxIcon.Information);
txtDeptName.Text = "";
ShowData();
}
else
{
MessageBox.Show("Unable to add Department", "SellRight", MessageBoxButtons.OK, MessageBoxIcon.Error);
txtDeptName.Text = "";
ShowData();
}
}
}
}
catch(Exception ex)
{
ex.ToString();
}
}
Upvotes: 0
Reputation: 2194
Alternatively and probably the most correct way to implement this is to use the provided ObservableCollection<T>
. It is designed with the sole purpose of implementing INotifyCollectionChanged
.
public partial class MyForm : Form
{
ObservableCollection<MyData> data = new ObservableCollection<MyData>();
public MyForm()
{
listBox1.DataSource = data;
listBox1.DisplayMember = "Name";
listBox1.ValueMember = "Id";
}
private void buttonAddData_Click(object sender, EventArgs e)
{
var selection = (MyData)comboBox1.SelectedItem;
data.Add(selection);
}
}
Because ObservableCollection<T>
implements INotifyCollectionChanged
the DataSource binding will automatically update the ListBox whenever your data changes.
Upvotes: 2
Reputation: 17590
I would suggest to use BindingSource
as it would properly update connected controls.
public partial class MyForm : Form
{
List<MyData> data = new List<MyData>();
BindingSource bs = new BindingSource();
public MyForm()
{
IntializeComponents();
bs.DataSource = data;
listBox1.DisplayMember = "Name";
listBox1.ValueMember = "Id";
listBox1.DataSource = bs;
}
private void buttonAddData_Click(object sender, EventArgs e)
{
var selection = (MyData)comboBox1.SelectedItem;
data.Add(selection);
bs.ResetBindings(false);
}
}
Changing controls data source on fly produces strange result sometime.
Upvotes: 37