2014-07-09 96 views
1

如何將ListBoxCheckedListBox與程序員定義的對象的List<>綁定?如何在綁定後編輯數據?我可以通過哪些對象修改數據?數據更改時如何更新列表框視圖?如何在用戶點擊CheckedListBox時檢索項目複選框的檢查狀態?如何在WinForms中管理與List <>綁定的ListBox/CheckedListBox?

我想分享一些我知道的知識,因爲我在這個主題上看到了很多線索,但沒有人清楚地表明如何處理數據綁定。不要誤解我的嘗試,我只想在其他方面表現出輕鬆的態度。

隨時發表評論。希望這會有所幫助!

+0

由於這是一個問答網站,你可能會考慮以這樣一種方式,它實際上是一個「問題」,而不僅僅是介紹教程改寫你的問題。 –

+0

修改爲符合問答風格。 – gfache

回答

1

以下「ListBox」與「listbox」不同,後者是用於ListBoxCheckedListBox的通用術語。


首先,綁定在testForm_Load事件處理程序中完成。必須告訴哪個對象將被綁定,以及要在列表框中顯示哪些屬性/字段。

((ListBox)m_checkedListBox).DataSource = m_underList; 
((ListBox)m_checkedListBox).DisplayMember = "PropToDisplay"; 

據我所知的過程中,結合的列表框表現得像一個只讀單向(數據源=>列表框)鏡圖。我們只能通過處理底層數據對象或控件的事件機制(忘記Items & co。)來影響列表框並檢索其數據。

對於CheckListBox,我們可以通過添加ItemCheckEventHandler方法將ItemCheck事件檢索選中的項,然後將其存儲到一個屬性的/字段的對象程序員定義的。

m_checkedListBox.ItemCheck += new ItemCheckEventHandler(this.ItemCheck); 

但是我們不能在定義數據源的內部檢查項目(基礎列表)的狀態,在CheckListBox檢查顯示。 CheckListBox看起來並沒有設計成這樣。

然後,可以通過底層列表隨意添加或刪除Userclass對象,或者調用所需的任何方法。只是不關心列表框。

m_underList.Add(new UserClass("Another example", 0, true)); 

最後,查看刷新的列表框。我看到很多關於將DataSource設置爲空的文章,然後將其重新分配回其先前的對象。我尋找更好的方法來做到這一點(更好或更漂亮?)。下面的方法很簡單。

void refreshView(ListBox lb, object dataSource); 

參考文獻:

有關從列表框檢索用戶選擇的補充信息,請訪問:MSDN ListControl Class Examples

下面是一個CheckedListBox的簡單示例的整個代碼被綁定,填充數據並清除。爲了簡單起見,我從從列表框或數據列表排序的原則入手。


UserClass.cs:Class用於存儲顯示/檢查的狀態/隱藏數據

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace TestForm 
{ 
    class UserClass 
    { 
     private int m_underProp; 

     // ctors 
     public UserClass(string prop2Disp, int anotherObj, bool isChecked = false) 
     { 
      PropToDisplay = prop2Disp; 
      IsChecked = isChecked; 
      AnotherProp = anotherObj; 
     } 

     public UserClass() 
     { 
      PropToDisplay = string.Empty; 
      IsChecked = false; 
      AnotherProp = 0; 
     } 

     // Property to be displayed in the listbox 
     public string PropToDisplay 
     { 
      get; 
      set; 
     } 

     // For CheckedListBox only! 
     // Property used to store the check state of a listbox 
     // item when a user select it by clicking on his checkbox 
     public bool IsChecked 
     { 
      get; 
      set; 
     } 

     // Anything you want 
     public int AnotherProp 
     { 
      get 
      { 
       return m_underProp; 
      } 

      set 
      { 
       m_underProp = value; 
       // todo, processing... 
      } 
     } 

     // For monitoring 
     public string ShowVarState() 
     { 
      StringBuilder str = new StringBuilder(); 

      str.AppendFormat("- PropToDisplay: {0}", PropToDisplay); 
      str.AppendLine(); 
      str.AppendFormat("- IsChecked: {0}", IsChecked); 
      str.AppendLine(); 
      str.AppendFormat("- AnotherProp: {0}", AnotherProp.ToString()); 

      return str.ToString(); 
     } 
    } 
} 

TestForm.Designer.cs:形式

namespace TestForm 
{ 
    partial class testForm 
    { 
     /// <summary> 
     /// Required designer variable. 
     /// </summary> 
     private System.ComponentModel.IContainer components = null; 

     /// <summary> 
     /// Clean up any resources being used. 
     /// </summary> 
     /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> 
     protected override void Dispose(bool disposing) 
     { 
      if (disposing && (components != null)) 
      { 
       components.Dispose(); 
      } 
      base.Dispose(disposing); 
     } 

     #region Windows Form Designer generated code 

     /// <summary> 
     /// Required method for Designer support - do not modify 
     /// the contents of this method with the code editor. 
     /// </summary> 
     private void InitializeComponent() 
     { 
      this.m_checkedListBox = new System.Windows.Forms.CheckedListBox(); 
      this.m_toggle = new System.Windows.Forms.Button(); 
      this.SuspendLayout(); 
      // 
      // m_checkedListBox 
      // 
      this.m_checkedListBox.CheckOnClick = true; 
      this.m_checkedListBox.FormattingEnabled = true; 
      this.m_checkedListBox.Location = new System.Drawing.Point(13, 13); 
      this.m_checkedListBox.Name = "m_checkedListBox"; 
      this.m_checkedListBox.Size = new System.Drawing.Size(171, 109); 
      this.m_checkedListBox.TabIndex = 0; 
      // 
      // m_toggle 
      // 
      this.m_toggle.Location = new System.Drawing.Point(190, 53); 
      this.m_toggle.Name = "m_toggle"; 
      this.m_toggle.Size = new System.Drawing.Size(75, 23); 
      this.m_toggle.TabIndex = 1; 
      this.m_toggle.Text = "Fill"; 
      this.m_toggle.UseVisualStyleBackColor = true; 
      this.m_toggle.Click += new System.EventHandler(this.m_toggle_Click); 
      // 
      // testForm 
      // 
      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
      this.ClientSize = new System.Drawing.Size(275, 135); 
      this.Controls.Add(this.m_toggle); 
      this.Controls.Add(this.m_checkedListBox); 
      this.Name = "testForm"; 
      this.Text = "Form"; 
      this.Load += new System.EventHandler(this.testForm_Load); 
      this.ResumeLayout(false); 

     } 

     #endregion 

     private System.Windows.Forms.CheckedListBox m_checkedListBox; 
     private System.Windows.Forms.Button m_toggle; 
    } 
} 

設計

TestForm.cs:格式爲

012的行爲
using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 
using System.Diagnostics; 
using System.IO; 

namespace TestForm 
{ 
    public partial class testForm : Form 
    { 
     // a List which will contain our external data. Named as the underlying list 
     private List<UserClass> m_underList; 

     public testForm() 
     { 
      InitializeComponent(); 

      m_underList = new List<UserClass> (3); 
     } 

     private void testForm_Load(object sender, EventArgs e) 
     { 
      // Bind the CheckedListBox with the List 
      // The DataSource property is hidden so cast the object back to ListBox 
      ((ListBox)m_checkedListBox).DataSource = m_underList; 

      // Tell which property/field to display in the CheckedListBox 
      // The DisplayMember property is hidden so cast the object back to ListBox 
      ((ListBox)m_checkedListBox).DisplayMember = "PropToDisplay"; 

      /* 
      * The CheckedListBox is now in "read-only" mode, that means you can't add/remove/edit 
      * items from the listbox itself or edit the check states. You can't access 
      * the underlying list through the listbox. Considers it as a unidirectionnal mirror 
      * of the underlying list. The internal check state is disabled too, however 
      * the ItemCheck event is still raised... 
      */ 

      // Manually set the ItemCheck event to set user defined objects 
      m_checkedListBox.ItemCheck += new ItemCheckEventHandler(this.ItemCheck); 
     } 

     private void ItemCheck(object sender, ItemCheckEventArgs evnt) 
     { 
      if (sender == m_checkedListBox) 
      { 
       if (!m_checkedListBox.Sorted) 
       { 
        // Set internal object's flag to remember the checkbox state 
        m_underList[evnt.Index].IsChecked = (evnt.NewValue != CheckState.Unchecked); 

        // Monitoring 
        Debug.WriteLine(m_underList[evnt.Index].ShowVarState()); 
       } 
       else 
       { 
        // If sorted... DIY 
       } 
      } 
     } 

     private void m_toggle_Click(object sender, EventArgs e) 
     { 
      if (sender == m_toggle) 
      { 
       if (m_toggle.Text == "Fill") 
       { 
        // Fill the checkedListBox with some data 
        // Populate the list with external data. 
        m_underList.Add(new UserClass("See? It works!", 42)); 
        m_underList.Add(new UserClass("Another example", 0, true)); 
        m_underList.Add(new UserClass("...", -7)); 
        m_toggle.Text = "Clear"; 
       } 
       else 
       { 
        // Empty the checkedListBox 
        m_underList.Clear(); 
        m_toggle.Text = "Fill"; 
       } 

       // Refresh view 
       // Remember CheckedListBox inherit from ListBox 
       refreshView(m_checkedListBox, m_underList); 
      } 
     } 

     // Magic piece of code which refresh the listbox view 
     void refreshView(ListBox lb, object dataSource) 
     { 
      CurrencyManager cm = (CurrencyManager)lb.BindingContext[dataSource]; 
      cm.Refresh(); 
     } 
    } 
} 

這裏是形式的意見。第一張圖片是加載時的圖片,第二張圖片是點擊「填充」按鈕時的圖片。有人可能會注意到,雖然IsChecked屬性在添加到數據源時設置爲true,但列表框中的第二項不會被檢查。

Form loadedFill button clicked

+0

有人可能會注意到儘管IsChecked屬性設置爲true,仍未檢查列表框中的第二項。所以它不起作用? – LarsTech

+0

設置數據列表中對象的'IsChecked'屬性不會影響鏡像項目複選框的檢查狀態,是的。 – gfache

相關問題