方法一:可随意设置下拉框的样式
(重点是下拉界面dropDownForm的相关设置)
myComboBox(可能是textBox 或 label):使用TextBox时可以实现可编辑下拉框
dropDownForm 为 Form
1、下拉界面的位置
dropDownForm.Location = myComboBox.Parent.PointToScreen( new Point( myComboBox.Left, myComboBox.Bottom) );
2、下拉界面相关设置
-
无边框:dropDownForm.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
-
不在任务栏展示界面: dropDownForm.ShowInTaskbar = false;
-
界面展示在最顶层:dropDownForm .TopMost = true;
3、下拉界面的显示、隐藏、释放
当myComboBox获取到焦点时展示界面dropdownForm.Show(),
当myComboBox失去焦点时隐藏界面dropdownForm.Hide(),
当包含自定义下拉框的界面关闭时释放界面dropdownForm.Dispose();
方法二:通过继承ComboBox来实现自定义下拉框
主要目的是实现自己想要的选项样式
案例:实现可编辑、选项可变,可自动筛选的下拉框
1、设置DrawMode = DrawMode.OwnerDrawFixed;
2、重写 OnDrawItem(DrawItemEventArgs e) 方法
protected override void OnDrawItem(DrawItemEventArgs e)
{
if (e.Index >= 0 && Items.Count > e.Index)
{
Dish dish = this.Items[e.Index] as Dish;
Rectangle rect = e.Bounds;
Point upCenter = new Point(rect.X + rect.Width / 2, rect.Top);
Point bottomCenter = new Point(rect.X + rect.Width / 2, rect.Bottom);
if ((e.State & DrawItemState.Selected) != 0)
e.Graphics.FillRectangle(new SolidBrush(SystemColors.Highlight), rect);
else
e.Graphics.FillRectangle(new SolidBrush(SystemColors.Window), rect);
e.Graphics.DrawRectangle(new Pen(SystemColors.ActiveBorder), rect);
e.Graphics.DrawLine(new Pen(SystemColors.ActiveBorder), upCenter, bottomCenter);
Font font = new Font("微软雅黑", 9F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(134)));
double width = e.Graphics.MeasureString(dish.Cuisine, font).Width;
double maxWidth = rect.Width / 2;
string cuisine = dish.Cuisine;
while(width >maxWidth && cuisine != "")
{
cuisine = cuisine.Remove(cuisine.Length - 1, 1);
width = e.Graphics.MeasureString(cuisine, font).Width;
}
e.Graphics.DrawString(cuisine, font, Brushes.Black, rect.X + 3, rect.Y + 3);
e.Graphics.DrawString(dish.DishName, font, Brushes.Black, upCenter);
}
}
3、若DropDownStyle == ComboBoxStyle.DropDown,则下拉框可编辑
需要对手动编辑的选项做处理,在回车时做处理。
重写ProcessCmdKey(ref Message msg, Keys keyData)【该方法尽量不要用】
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Enter && this.Focused)
{
//当手动编辑的文本不能转为已有选项时,SelectItem会为null,回车时编辑的文本就会被清空
//需要手动添加新的选项
if (SelectedItem == null)
{
if (Text.Contains("_") && !Items.Contains(new Dish(Text.Split('_').First(), Text.Split('_').Last())))
{
Items.Insert(0, new Dish(Text.Split('_').First(), Text.Split('_').Last()));
SelectedItem = Items[0];
}
}
}
return base.ProcessCmdKey(ref msg, keyData);
}
4、可自动筛选
方法一:设置AutoCompleteSource = AutoCompleteSource.CustomSource,同时使用this.Sorted = true排序,在效果上,当选项多时会有卡顿
AutoCompleteSource = AutoCompleteSource.CustomSource;
AutoCompleteMode = AutoCompleteMode.SuggestAppend;
AutoCompleteStringCollection items = new AutoCompleteStringCollection();
foreach (Dish item in value)
items.Add(item.ToString());
AutoCompleteCustomSource = items;
设置排序
this.Sorted = true
5、可自动筛选
方法二:设置AutoComPleteMode = AutoCompleteMode.SuggestAppend;但是不设置AutoCompleteSource ,选项自己排序后添加到Items中
如List<string> datas排序
data.Sort((x,y) => x.CompareTo(y)); 即可实现排序
6、展开下拉界面:想要在输入时展开下拉界面,不能在OnTextChanged中做处理,可以在OnEnter和OnKeyDown中做处理,设置this.DroppedDown = true;
选项需要排序,当在编辑文本时,下拉界面的滑动条会自动移动到匹配项附近
//实现在开始编辑下拉框时展开下拉界面, 在设置筛选后,且选项已经排序过,下拉界面中滑动条会自动移动到匹配项附近
protected override void OnEnter(EventArgs e)
{
this.DroppedDown = true;
base.OnEnter(e)
}
//实现当删除编辑文本时展开下拉界面
protected override void OnKeyDown(KeyEventArgs e)
{
if(e.KeyData == Keys.Back || e.KeyData == Keys.Delete)
this.DroppedDown = true;
base.OnKeyDown
}
7、解决输入在选项中不存在导致报错的问题
在TextChanged事件中将不存在的选项添加到选项中,
myComboBox.Items.Add(输入的选项)