想做一个有下拉框的标签框类似于easyui tagbox这个插件:
一个combox,可以多选显示在输入框内。
便于查看、编辑。
找了下winform的自带控件,没有。查了查资料,琢磨着自己做一个,刚好放在和B/S端的easyui TagBox对应起来。
拆解一下这个tagbox :
多选combox。。。。但是combox 没办法放标签控件!!
所以索性把combox一起做了吧:
一个带边框的 panel = (内部一个后期放标签的panel+一个按钮Button)
还有一个陈列标签选项的listbox.
组合起来就是:tagBox = (大)panel+listbox。
好了,新建一个用户控件:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace ProjectTest
{
public partial class TagBoxControl : UserControl
{
public CheckedListBox CheckedListBox { get; set; } //为选项赋值的接口
public List<string> SelectedItems1 { get; set; } //传递已选择项目的接口
public Panel panel1 = new Panel();
private Panel panel2 = new Panel();
private int p1Height = 30;
public int panel1Height
{
get{return p1Height;}
set{
p1Height = value;
panel1.Height = value;
}
}
public TagBoxControl()
{
SelectedItems1 = new List<string>();
this.VerticalScroll.Enabled = true;
this.AutoSize = true;
Button btn = new Button();
btn.Text = "v";
btn.Width = 18;
btn.FlatStyle = FlatStyle.Flat;
btn.FlatAppearance.BorderSize = 0;
btn.BackColor = Color.White;
btn.Click += new EventHandler(btn_Click);
btn.Dock = DockStyle.Right;
btn.Margin = new Padding(0);
panel2.BackColor = System.Drawing.SystemColors.Window;
panel2.Dock = DockStyle.Fill;
panel2.Margin = new Padding(0);
panel2.AutoScroll = true;
panel2.AutoScrollMinSize = new System.Drawing.Size(this.Width, this.panel2.Height-2);
panel2.VerticalScroll.Visible = true;//竖的
panel2.HorizontalScroll.Visible = false;//横的
panel1.BorderStyle = BorderStyle.FixedSingle;
panel1.Margin = new Padding(0);
panel1.Dock = DockStyle.Top;
panel1.Height = p1Height;
panel1.BackColor = System.Drawing.SystemColors.Window;
panel1.Controls.Add(panel2);
panel1.Controls.Add(btn);
CheckedListBox = new CheckedListBox();
CheckedListBox.CheckOnClick = true;
CheckedListBox.MultiColumn = true;
CheckedListBox.Visible = false;
CheckedListBox.HorizontalScrollbar = false;
CheckedListBox.MouseUp += MouseUp1;
CheckedListBox.MouseLeave += MouseLeave1;
this.Controls.Add(panel1);
InitializeComponent();
}
#region 订阅方法模块
private void MouseLeave1(object sender, EventArgs e) //鼠标离开CheckedListBox,隐藏CheckedListBox
{
CheckedListBox.Hide();
}
private void MouseUp1(object sender, EventArgs e) //在CheckedListBox中选择后,在Panel2中显示相应项目
{
SetPanelData();
}
private void btn_Click(object sender, EventArgs e)
{
if (CheckedListBox.Visible)
{
return;
}
else
{
CheckedListBox.Width = panel1.Width;
CheckedListBox.Size = new Size(panel1.Width, 100);
CheckedListBox.Location = new Point(panel1.Left, panel1.Height);
Controls.Add(CheckedListBox);
CheckedListBox.Visible = true;
}
}
#endregion
private void SetPanelData() //设置panel数据
{
this.panel2.Controls.Clear();
var list = new List<string>();
foreach (var v in CheckedListBox.CheckedItems) //将选择的项目加入list
{
list.Add(v.ToString());
}
Double tmp = (double)this.panel2.Width / (double)(100);//panel/btn.width 一行显示几个
int colNum = (int)Math.Floor(tmp); //向下取整
tmp = (double)list.Count / (double)colNum; //选中个数/一行几个
int rowNum = (int)Math.Ceiling(tmp);//几行
for (int i = 0; i < list.Count; i++)
{
Button btn = new Button();
if (i % 2 == 0)
{
btn.BackColor = Color.LightGoldenrodYellow;
}
else
{
btn.BackColor = Color.LightGreen;
}
btn.Click += new EventHandler(btnRemo_Click);
btn.Width = 100;
btn.Height = 25;
btn.Text = list[i];
btn.Location = new Point((i % colNum) * btn.Width, (i / colNum) * btn.Height);
this.panel2.Controls.Add(btn);
}
SelectedItems1 = list; //对外数据赋值
}
void btnRemo_Click(object sender, EventArgs e)//移除
{
Button btn = sender as Button;
for (int i = 0; i < CheckedListBox.Items.Count; i++)
{
var tmp = CheckedListBox.Items[i].ToString();
if (tmp == btn.Text)
{
CheckedListBox.SetItemChecked(i, false);
}
}
SetPanelData();
}
public void InitView() //初始页面
{
this.panel2.Controls.Clear();
for (int i = 0; i < CheckedListBox.Items.Count; i++)
{
var tmp = this.SelectedItems1.Contains(CheckedListBox.Items[i].ToString());
CheckedListBox.SetItemChecked(i, tmp);
}
SetPanelData();
}
}
}
直接上代码,怼上去就能用:
Form搞个测试:
?for (int i=0;i<100;i++)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? this.tagBoxControl1.CheckedListBox.Items.Add("标签"+i);
? ? ? ? ? ? }
其中panel内的标签是按钮,设置了个点击事件,双击移除,可以获取所有选中的标签。基本功能没毛病,有需要的按照自己需求拿回去再改改,优化下直接用。
留个痕迹,指不定啥时候就能用得到了。