2013-07-12 164 views
33

フォームには、1つのComboboxと1つのListBoxがあります。 "Add"ボタンをクリックすると、ComboBoxからListBoxに選択したアイテムを追加したいと思います。C#WinFormsのListBoxのDataSourceを更新する方法

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

} 

この例では、選択した項目がListBox内の新しい項目に置き換えられます。アイテムをリストに追加する必要があります。

私のコードで何が問題になっていますか?

ありがとうございました。

+0

'ShowData()'と 'LoadData()'に違いはありますか、それとも間違いですか? – dwonisch

+0

LoadData()のコード?このリストボックスについて投稿したものはありません。 –

+0

との問題があります。それはShowData()です。申し訳ありませんが、良い目です。 – panjo

答えて

47

listbox1.DataSourceプロパティは、値の変更のためではなく、で検索します値が実際に変わらない同じリストを常に割り当てます。

List<T>の代わりにBindingList<T>を使用して、追加された新しいアイテムを自動的に認識することができます。起動時に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); 
    } 
} 
+3

'ShowData()'メソッドの最初の行に 'listBox1.DataSource = null;'を追加するだけです – NoviceProgrammer

+2

これには一生懸命お世話になりました。マイクロソフトのチュートリアルをここで詳しくお読みください 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

ああ、これはかなりです。これを使用して、ListBoxをスクロール位置を不必要に乱さずにアイテムを編集するときにListBoxを更新することができます。 – Nyerguds

19

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

オンザフライでコントロールデータソースを変更すると、いつか奇妙な結果が生成されることがあります。

12

リストボックスは、DataSourceを変更したことを検出しませんでした。 Datasourceはそう最初にnullにDataSourceを設定し、変更されたときにのみ更新されます:

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

をあなたはまた、その後の項目をクリアすることができ、再びDataSourceを設定します。

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

DataSourceプロパティが設定されていると、アイテムコレクションを変更できません。したがって、2番目の例は機能しません。 –

+3

**注意事項:** 'listBox1.DataSource = null' *を設定すると、' DisplayMember'が空文字列に設定されます(ただし、 'ValueMember'は設定されません)。 (これをデバッガで.NET 4.0 WinFormsで検出します。)したがって、 'DisplayMember'と' ValueMember'を使用している場合は、 'DataSource'を' null'に設定した後、 'DisplayMember'を必ず再割り当てしてください。 – DavidRR

3

代わりに、おそらくこれを実装するための最も正しい方法は提供さObservableCollection<T>を使用することです。これは、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); 
    } 
} 

たびにデータが変更さObservableCollection<T>実装INotifyCollectionChanged DataSourceが結合が自動的にリストボックスを更新しますので。

0

コールShowData()フォームがBindingSourceDisplayMemberValueMemberは、部門が削除されると、以下の実装では

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

に設定されている初期化

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

ShowData()方法、であなたのリストボックスを埋めるために初期化しデータベースからリストボックスは現在のコレクションで最新表示されます

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(); 
     } 
    } 
関連する問題