C#ListBox更新项目更改

时间:2011-03-14 00:30:17

标签: c# winforms listbox

我有一个自定义对象列表,我已将其添加到WinForms C#4.0应用程序中的ListBox控件中。

当用户选择ListBox中的特定元素时,该对​​象的属性出现在各种输入字段中ListBox旁边的窗口中。用户可以更改这些并单击“保存”,这将修改对象的数据成员以与用户所做的更改相对应。

该功能确实有效。这些值将保存到对象中,当用户再次选择该元素时,将确认其更改已正确保存。

什么不起作用是更新ListBox中的文本。例如,如果我们在ListBox中有一个人员列表,我们可以在那里看到“John Smith”,我们可以点击他的名字 - 将他的名字编辑为“John Smithe”,然后点击OK。 ListBox仍显示“John Smith”,但是如果我们点击他的名字,那么在右侧的TextBox中我们可以看到他的名字已经被正确地改为“John Smithe”。

我尝试在ListBox上调用Refresh()方法,但这不起作用。

我可以通过从ListBox中删除项目并再次添加它来修复它。这是有效的,这不是一个真正的问题,因为无论如何项目都存储在不同的列表中,所以我没有失去任何员工的风险。

但这真的是最好的方法吗?是否有更优雅的方法来更新ListBox中的文本而无需再次删除/添加项目?

2 个答案:

答案 0 :(得分:3)

执行ListBox实施INotifyPropertyChanged

中的对象

<强>更新

您似乎可以通过几个步骤解决问题:

  1. DisplayMember的{​​{1}}属性设置为对象上的属性,该属性提供您希望在列表中显示的内容。我将假设此属性的名称为ListBox以获得此答案。
  2. 让对象实现DisplayText
  3. 在影响INotifyPropertyChanged值的所有属性的setter中,使用DisplayText为属性名称引发NotifyPropertyChanged事件。
  4. 然后你应该好好去。

答案 1 :(得分:2)

按照上面引用的教程,我做了一个使用BindingList的快速而又脏的例子。希望它对你有所帮助。

public partial class Listbox_Databinding : Form
{
    BindingList<Person> People = new System.ComponentModel.BindingList<Person>();

    public Listbox_Databinding()
    {
        InitializeComponent();

        People.Add(new Person("John", "Smith"));
        People.Add(new Person("John", "Jacob"));

        lstSelectPerson.DataSource = People;

    }

    private void lstSelectPerson_SelectedIndexChanged(object sender, EventArgs e)
    {
        txtLast.Text = ((Person)lstSelectPerson.SelectedItem).Last;
    }

    private void btnUpdate_Click(object sender, EventArgs e)
    {
        ((Person)lstSelectPerson.SelectedItem).Last = txtLast.Text;
    }
}

public class Person : INotifyPropertyChanged
{
    public Person(string first, string last)
    {
        First = first;
        Last = last;
    }

    public override string ToString()
    {
        return Last + ", " + First;
    }

    string p_first;
    string p_last;

    public string First
    {
        get { return p_first; }
        set
        {
            p_first = value;
            OnDisplayPropertyChanged();
        }
    }

    public string Last
    {
        get { return p_last; }
        set
        {
            p_last = value;
            OnDisplayPropertyChanged();
        }
    }

    void OnDisplayPropertyChanged()
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs("DisplayName"));
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion
}