如何在c# WinForms中刷新列表框的数据源

时间:2022-09-02 08:28:51

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.

表单有一个组合框和一个列表框。单击“添加”按钮时,我想将ComboBox中选中的项添加到列表框中。

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?

我的代码有什么问题?

Thanks.

谢谢。

5 个解决方案

#1


51  

listbox1.DataSource property looks for value changes but by assigning the same list all the time the value won't really change.

listbox1。DataSource属性查找值的更改,但通过始终分配相同的列表,该值不会真正更改。

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.

您可以使用BindingList ,而不是您的List ,以自动识别添加的新项。必须在启动时调用ShowData()方法一次。

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);
    }
}

#2


19  

I would suggest to use BindingSource as it would properly update connected controls.

我建议使用BindingSource,因为它可以正确地更新已连接的控件。

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.

动态更改控件数据源有时会产生奇怪的结果。

#3


12  

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:

列表框没有检测到您更改了数据源。它只在数据源发生更改时刷新,因此将Datasource设置为null:

 listBox1.DataSource = null;
 listBox1.DataSource = data;

You could also clear the items then set the DataSource again:

您还可以清除项目,然后再次设置数据源:

listBox1.Items.Clear();
listBox1.DataSource = data;

#4


3  

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.

另外,实现这一点的最正确的方法可能是使用所提供的ObservableCollection 。它的唯一目的是实现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.

因为ObservableCollection 实现INotifyCollectionChanged,所以每当您的数据发生变化时,数据源绑定都会自动更新列表框。

#5


0  

Call ShowData() when the form initializes to populate your listbox on initialization

当表单初始化时,调用ShowData()来填充初始化的列表框。

 public Department()
        {
            InitializeComponent();
            ShowData();
        }

ShowData() Method, where BindingSource, DisplayMember and ValueMember are set

ShowData()方法,其中设置了BindingSource、DisplayMember和ValueMember

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

在下面的实现中,当一个部门从数据库中删除时,listbox会刷新当前的集合。

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();
        }
    }

#1


51  

listbox1.DataSource property looks for value changes but by assigning the same list all the time the value won't really change.

listbox1。DataSource属性查找值的更改,但通过始终分配相同的列表,该值不会真正更改。

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.

您可以使用BindingList ,而不是您的List ,以自动识别添加的新项。必须在启动时调用ShowData()方法一次。

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);
    }
}

#2


19  

I would suggest to use BindingSource as it would properly update connected controls.

我建议使用BindingSource,因为它可以正确地更新已连接的控件。

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.

动态更改控件数据源有时会产生奇怪的结果。

#3


12  

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:

列表框没有检测到您更改了数据源。它只在数据源发生更改时刷新,因此将Datasource设置为null:

 listBox1.DataSource = null;
 listBox1.DataSource = data;

You could also clear the items then set the DataSource again:

您还可以清除项目,然后再次设置数据源:

listBox1.Items.Clear();
listBox1.DataSource = data;

#4


3  

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.

另外,实现这一点的最正确的方法可能是使用所提供的ObservableCollection 。它的唯一目的是实现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.

因为ObservableCollection 实现INotifyCollectionChanged,所以每当您的数据发生变化时,数据源绑定都会自动更新列表框。

#5


0  

Call ShowData() when the form initializes to populate your listbox on initialization

当表单初始化时,调用ShowData()来填充初始化的列表框。

 public Department()
        {
            InitializeComponent();
            ShowData();
        }

ShowData() Method, where BindingSource, DisplayMember and ValueMember are set

ShowData()方法,其中设置了BindingSource、DisplayMember和ValueMember

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

在下面的实现中,当一个部门从数据库中删除时,listbox会刷新当前的集合。

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();
        }
    }