2013-07-12 14 views
33

Formularz ma jeden Combobox i jeden ListBox. Po kliknięciu przycisku "Dodaj" chcę dodać wybrany element z ComboBox do ListBox.Jak odświeżyć DataSource ListBox w C# WinForms

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

} 

W tym przykładzie wybrany element zostanie zastąpiony nowym zaznaczeniem wewnątrz ListBox. Muszę dodać przedmiot do listy.

Co jest nie tak z moim kodem?

Dzięki.

+0

Czy istnieje różnica między 'ShowData()' i 'LoadData()' lub czy jest to błąd? – dwonisch

+0

Kod dla LoadData()? Nie ma nic w tym, co napisałeś o tym tutaj listbox masz problem z –

+0

to ShowData(), przepraszam, ale dobre oko. – panjo

Odpowiedz

47

listbox1.DataSource nieruchomość wygląda na zmiany wartości, ale przez przypisywanie tej samej listy przez cały czas, gdy jej wartość naprawdę się nie zmieni.

Możesz użyć BindingList<T>, zamiast swojego List<T>, aby automatycznie rozpoznać nowe dodane elementy. Twoja metoda ShowData() musi zostać wywołana jeden raz podczas uruchamiania.

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

po prostu dodaj 'listBox1.DataSource = null;' jako pierwszą linię do metody 'ShowData()' – NoviceProgrammer

+2

dziękuję za to, spędziłem godzinę próbując dowiedzieć się, dlaczego mój listbox nie wyświetliłby moich rzeczy poprawnie, nawet po następujące instrukcje tutoriala microsoft tutaj dokładnie http://msdn.microsoft.com/en-us/library/system.windows.forms.listcontrol.datasource.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet- 2 – Aralox

+0

Och, to jest piękne. Mogę tego użyć, aby odświeżyć ListBox podczas edycji elementów bez konieczności niepotrzebnego zrolowania pozycji przewijania. – Nyerguds

19

Proponuję użyć BindingSource, ponieważ prawidłowo zaktualizuje podłączone elementy sterujące.

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

Zmiana źródła danych sterujących na bieżąco powoduje, że czasami pojawia się dziwny wynik.

12

Listbox nie wykrył, że zmieniono DataSource. Będzie odświeżyć tylko gdy Datasource uległa zmianie, więc ustawić DataSource null pierwszy:

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

Można również usunąć elementy następnie ustawić DataSource ponownie:

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

Gromadzenie elementów nie może być modyfikowane po ustawieniu właściwości DataSource. Drugi przykład nie zadziała. –

+3

** Uwaga ostrzegawcza: ** Ustawienie 'listBox1.DataSource = null' * także * ustawia' DisplayMember' na pusty ciąg znaków (ale nie "ValueMember"). (Odkryłem to w debugerze z .NET 4.0 WinForms.) Zatem, jeśli używasz 'DisplayMember' i' ValueMember', pamiętaj o ponownym przypisaniu 'DisplayMember' po ustawieniu' DataSource' na 'null'. – DavidRR

3

Alternatywnie i prawdopodobnie najbardziej poprawny sposób wdrożenia tego jest użycie dostarczonego ObservableCollection<T>. Został zaprojektowany wyłącznie w celu implementacji 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); 
    } 
} 

Ponieważ ObservableCollection<T> narzędzia INotifyCollectionChanged DataSource wiązania automatycznie zaktualizować pole listy w miarę zmiany danych.

0

połączeń ShowData() gdy postać inicjuje aby zapełnić listbox na inicjalizacji

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

ShowData() metodzie, gdzie BindingSource, DisplayMember i ValueMember są ustawione

private void ShowData() 
      { 
       using (var uow = new UnitOfWork(new SellContext())) 
       { 
        listBox1.DataSource = uow.Departments.GetAll().ToList(); 
        listBox1.DisplayMember = "DepartmentName"; 
        listBox1.ValueMember = "DepartmentId"; 
        //listBox1.Invalidate();  
       } 
      } 

W realizacji poniższej gdy dział zostanie usunięty z bazy danych listbox odświeża się z bieżącą kolekcją

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