[C#]ListBox如何偵測Item的新增、插入、與刪除

[C#]ListBox如何偵測Item的新增、插入、與刪除

有時候我們使用ListBox元件會想要針對Item的新增、插入、與刪除做些反應,可能像是有個Item插入時我們會想把游標移到最下面之類的。但內建的ListBox並未將這樣的訊息開放出來,所以我們無法直接的去做這樣的處理,必須要自行去接收視窗訊息才行。

 

我們可以建立個控制項,繼承自ListBox,並視需要來接收想要處理的視窗訊息。像是想要偵測Item新增的話我們可以偵測LB_ADDSTRING、想要偵測Item插入的話可以偵測LB_INSERTSTRING、想要偵測Item刪除的話可以偵測LB_DELETESTRING。


			private const int LB_INSERTSTRING = 0x181;
			private const int LB_DELETESTRING = 0x182; 

 

偵測時需覆寫WndProc方法,並在方法內判斷Msg是否是我們所感興趣的訊息。有的訊息會內含較為詳細的資訊,像是Item的索引與值,若有需要可從wparam與lparam中擷取。


			{
				var itemIndex = 0;
				var itemValue = string.Empty;

				switch (m.Msg)
				{
					case LB_ADDSTRING:
						itemValue = Marshal.PtrToStringUni(m.LParam);
						OnItemAdded(EventArgs.Empty);
						break;
					case LB_INSERTSTRING:
						itemIndex = (int)m.WParam;
						itemValue = Marshal.PtrToStringUni(m.LParam);
						OnItemInserted(EventArgs.Empty);
						break;
					case LB_DELETESTRING:
						itemIndex = (int)m.WParam;
						OnItemDeleted(EventArgs.Empty);
						break;
					default:
						break;
				}
				base.WndProc(ref m);
			} 

 

這邊附上較為完整的測試範例:


using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication4
{
	public partial class Form1 : Form
	{
		class ListBoxEx : ListBox
		{
			#region Const
			private const int LB_ADDSTRING = 0x180;
			private const int LB_INSERTSTRING = 0x181;
			private const int LB_DELETESTRING = 0x182; 
			#endregion


			#region Event
			public event EventHandler ItemAdded;
			public event EventHandler ItemInserted;
			public event EventHandler ItemDeleted;
			#endregion


			#region Protected Method
			protected void OnItemAdded(EventArgs e)
			{
				if (ItemAdded == null)
					return;
				ItemAdded(this, e);
			}

			protected void OnItemInserted(EventArgs e)
			{
				if (ItemInserted == null)
					return;
				ItemInserted(this, e);
			}

			protected void OnItemDeleted(EventArgs e)
			{
				if (ItemDeleted == null)
					return;
				ItemDeleted(this, e);
			}

			protected override void WndProc(ref Message m)
			{
				var itemIndex = 0;
				var itemValue = string.Empty;

				switch (m.Msg)
				{
					case LB_ADDSTRING:
						itemValue = Marshal.PtrToStringUni(m.LParam);
						OnItemAdded(EventArgs.Empty);
						break;
					case LB_INSERTSTRING:
						itemIndex = (int)m.WParam;
						itemValue = Marshal.PtrToStringUni(m.LParam);
						OnItemInserted(EventArgs.Empty);
						break;
					case LB_DELETESTRING:
						itemIndex = (int)m.WParam;
						OnItemDeleted(EventArgs.Empty);
						break;
					default:
						break;
				}
				base.WndProc(ref m);
			} 
			#endregion
		}

		#region Var
		private ListBoxEx _listBox; 
		#endregion


		#region Private Property
		private ListBoxEx m_ListBox
		{
			get
			{
				return _listBox ?? (_listBox = new ListBoxEx() 
				{
					Dock = DockStyle.Fill
				});
			}
		} 
		#endregion


		#region Constructor
		public Form1()
		{
			InitializeComponent();

			m_ListBox.ItemAdded += m_ListBox_ItemAdded;
			m_ListBox.ItemDeleted += m_ListBox_ItemDeleted;
			m_ListBox.ItemInserted += m_ListBox_ItemInserted;

			this.panel1.Controls.Add(m_ListBox);
		} 
		#endregion


		#region Event Process
		private void button1_Click(object sender, EventArgs e)
		{
			m_ListBox.Items.Add(Guid.NewGuid().ToString());
		}

		private void button2_Click(object sender, EventArgs e)
		{
			var index = m_ListBox.SelectedIndex >= 0 ? m_ListBox.SelectedIndex : 0;
			m_ListBox.Items.Insert(index, Guid.NewGuid().ToString());
		}

		private void button3_Click(object sender, EventArgs e)
		{
			if (m_ListBox.SelectedIndex == -1)
				return;
			m_ListBox.Items.RemoveAt(m_ListBox.SelectedIndex);
		}

		void m_ListBox_ItemInserted(object sender, EventArgs e)
		{
			lbxLog.Items.Add("Item inserted");
		}

		void m_ListBox_ItemDeleted(object sender, EventArgs e)
		{
			lbxLog.Items.Add("Item deleted");
		}

		void m_ListBox_ItemAdded(object sender, EventArgs e)
		{
			lbxLog.Items.Add("Item added");
		} 
		#endregion
	}
}

 

運行後的結果如下,新增、插入、與刪除都能夠即時的偵測。

image

 

Link