以下「ListBox
」與「listbox」不同,後者是用於ListBox
和CheckedListBox
的通用術語。
首先,綁定在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,但列表框中的第二項不會被檢查。
由於這是一個問答網站,你可能會考慮以這樣一種方式,它實際上是一個「問題」,而不僅僅是介紹教程改寫你的問題。 –
修改爲符合問答風格。 – gfache