2013-07-12 14 views
33

Il modulo ha una casella combinata e una casella di elenco. Quando si fa clic sul pulsante "Aggiungi", voglio aggiungere l'elemento selezionato dal ComboBox al ListBox.Come aggiornare DataSource di un ListBox in 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(); 
    } 

} 

Con questo esempio, l'elemento selezionato viene sostituito con la nuova selezione all'interno di ListBox. Devo aggiungere l'articolo alla lista.

Cosa c'è di sbagliato nel mio codice?

Grazie.

+0

C'è una differenza tra 'ShowData()' e 'LoadData()' o è un errore? Codice – dwonisch

+0

per LoadData()? Niente di tutto ciò che hai postato su questo elenco qui stai riscontrando un problema con –

+0

è ShowData(), mi dispiace, però occhio. – panjo

risposta

47

listbox1.DataSource proprietà sembra per variazioni di valore, ma da assegnando la stessa lista per tutto il tempo in cui il valore non cambierà davvero.

È possibile utilizzare uno BindingList<T>, anziché il List<T>, per riconoscere automaticamente i nuovi articoli aggiunti. Il tuo metodo ShowData() deve essere chiamato una volta all'avvio.

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

basta aggiungere 'listBox1.DataSource = null;' come prima linea al metodo 'ShowData()' – NoviceProgrammer

+2

grazie un sacco per questo, ho passato un'ora cercando di capire perché la mia lista non avrebbe mostrato i miei articoli correttamente, anche dopo seguendo il tutorial di microsoft qui da vicino 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

Oh, questo è carino. Posso usare questo per aggiornare il ListBox quando si modificano gli elementi in esso senza inutilmente rovinare la posizione di scorrimento. – Nyerguds

19

Vorrei suggerire di utilizzare BindingSource come aggiornerebbe correttamente i controlli collegati.

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

La modifica dell'origine dati di controllo al volo produce risultati strani a volte.

12

La casella di riepilogo non ha rilevato la modifica dello DataSource. Esso si aggiorna solo quando Datasource è cambiato, quindi impostare DataSource su null prima:

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

Si potrebbe anche cancellare le voci quindi impostare nuovamente il DataSource:

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

La raccolta di articoli non può essere modificata quando la proprietà DataSource è impostata. Quindi il secondo esempio non funzionerà. –

+3

** Una nota cautelativa: ** L'impostazione 'listBox1.DataSource = null' * anche * imposta' DisplayMember' sulla stringa vuota (ma non 'ValueMember'). (Scoperto nel debugger con .NET 4.0 WinForms.) Quindi, se stai usando 'DisplayMember' e' ValueMember', assicurati di riassegnare 'DisplayMember' dopo aver impostato' DataSource' su 'null'. – DavidRR

3

alternativa e probabilmente il modo più corretto per implementare questo è quello di utilizzare il previsto ObservableCollection<T>. È progettato con l'unico scopo di implementare 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); 
    } 
} 

Perché ObservableCollection<T> attrezzi INotifyCollectionChanged il DataSource vincolante aggiornerà automaticamente il ListBox ogni volta che la data cambia.

0

chiamata ShowData() quando il modulo inizializza per popolare il listbox su inizializzazione

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

ShowData() Method, in cui sono impostati

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

Nell'implementazione di seguito quando un reparto viene eliminato BindingSource, DisplayMember e ValueMember dal database la casella di riepilogo si aggiorna con la raccolta corrente

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