在Winform窗体上我们有时候会使用ListBox来展示数据,但是有时候我们希望能对ListBox里的数据进行编辑。通常我们可能会采用双击ListBox的Item后弹出一个InputBox来实现,不过我希望能来的直接一点,正如我标题上说的,双击ListBox后,将ListBox整个切换为TextBox,原来的ListBox里的文本在TextBox里通过换行显示。最终得到的效果如下面的GIF动图。
我写了一个ListBoxEditor的类,类代码如下所示。其主要是监听ListBox的双击鼠标事件,创建一个文本框控件,将ListBox控件的Item字符串值写入TextBox中。在文本框中双击或者文本框失去焦点时,重新切换为ListBox控件。
ListBoxEditor.cs
public class ListBoxEditor { public ListBoxEditor(ListBox listBox,string itemSplitter=";") { ListBox = listBox; ItemSplitter = itemSplitter; } private ListBox _listBox; public ListBox ListBox { get { return _listBox; } set { _listBox = value; if (_listBox != null) { _listBox.MouseDoubleClick += ListBoxMouseDoubleClick; } } } private string _itemSplitter; public string ItemSplitter { get { return _itemSplitter; } set { _itemSplitter = value; } } private TextBox _txtBox; private void ListBoxMouseDoubleClick(object sender, MouseEventArgs e) { if (_txtBox == null){ _txtBox = new TextBox(); } string str = null; for (int i = 0; i < ListBox.Items.Count; i++) { if (i == 0) { str = ListBox.Items[i].ToString(); } else { str += ItemSplitter + ListBox.Items[i].ToString(); } } _txtBox.Font = ListBox.Font; _txtBox.Multiline = true; _txtBox.WordWrap = true; _txtBox.ScrollBars = ScrollBars.Vertical; _txtBox.Text = str; ListBox.Parent.Controls.Add(_txtBox); _txtBox.Location = ListBox.Location; _txtBox.Size = ListBox.Size; _txtBox.Visible = true; _txtBox.BringToFront(); _txtBox.LostFocus += TextBoxLostFocus; _txtBox.MouseDoubleClick += TextBoxMouseDoubleClick; _txtBox.Focus(); } private void TextBoxMouseDoubleClick(object sender, MouseEventArgs e) { CloseTextBox(); } private void TextBoxLostFocus(object sender, EventArgs e) { CloseTextBox(); } private void CloseTextBox() { string[] strs = Regex.Split(_txtBox.Text, ItemSplitter, RegexOptions.IgnoreCase); ListBox.DataSource = null; if (strs != null && strs.Count() > 0) { ListBox.DataSource= strs; } ListBox.Parent.Controls.Remove(_txtBox); _txtBox = null; } }
使用方法:在需要实现ListBox双击使用文本框进行编辑的窗体中,使用如下的代码来启用功能:
public frmSysSetting() { InitializeComponent(); editor = new ListBoxEditor(lstMailTo, Environment.NewLine);//为收件人列表框初始化一个编辑器,分隔符为换行符 }