2011-03-14 85 views
3

我有一個自定義對象的列表,我添加到我的WinForms C#4.0應用程序的ListBox控件。C#列表框更新項目更改

當用戶選擇列表框中的某個元素時,該對​​象的屬性出現在各種輸入字段中列表框旁邊的窗口中。用戶可以改變這些並點擊'保存',這將修改對象的數據成員以符合用戶所做的更改。

該功能確實有效。這些值被保存到對象中,並且當用戶再次選擇該元素時,他們的改變被確認保存正確。

不工作的是ListBox中文本的更新。例如,如果我們有一個列表框中的工作人員列表,我們可以在那裏看到「John Smith」,我們可以點擊他的名字 - 編輯他的名字爲「John Smithe」,然後單擊確定。列表框仍然顯示「John Smith」,但是如果我們點擊他的名字,那麼在右邊的文本框中,我們可以看到他的名字已經正確地更改爲「John Smithe」。

我已經嘗試調用列表框上的Refresh()方法,但這不起作用。

我可以通過從列表框中刪除項目並再次添加它來解決它。這是有效的,這不是一個真正的問題,因爲這些項目被存儲在單獨的列表中,所以我沒有失去任何員工的風險。

但是,這真的是最好的方式嗎?有沒有更好的方法來更新列表框中的文本,而無需再次刪除/添加項目?

回答

3

ListBox的對象是INotifyPropertyChanged的對象嗎?

更新:

似乎可以解決幾個步驟的問題:

  1. ListBoxDisplayMember屬性設置爲一個屬性上的對象,提供不管它是什麼你想出現在列表中。我會假設這個屬性被命名爲DisplayText爲這個答案。
  2. 讓對象實現INotifyPropertyChanged
  3. 在影響DisplayText值的所有屬性的設置程序中,將NotifyPropertyChanged事件與DisplayText一起提升爲屬性名稱。

你應該很好去。

+1

不,他們不... – Ozzah 2011-03-14 00:46:39

+2

尼斯教程這裏:http://www.codeproject.com/KB/cs/BindBetterINotifyProperty.aspx – 2011-03-14 01:25:02

+0

完美的作品。只是一個評論,因爲我剛纔有這個問題:這隻適用於使用「數據源」(如在教程中)。如果您使用ListBox的「Items」屬性,它不起作用! – Knowleech 2016-08-06 16:39:49

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 
}