* UIComboBox: 增加过滤

This commit is contained in:
Sunny 2022-04-15 23:41:32 +08:00
parent 8beb5042ca
commit 38908bbab6
3 changed files with 245 additions and 38 deletions

View File

@ -184,7 +184,7 @@ namespace Sunny.UI
public bool DroppedDown => itemForm is { Visible: true }; public bool DroppedDown => itemForm is { Visible: true };
private int symbolNormal = 61703; private int symbolNormal = 61703;
private int dropSymbol = 61703; protected int dropSymbol = 61703;
[DefaultValue(61703)] [DefaultValue(61703)]
[Description("正常显示时字体图标"), Category("SunnyUI")] [Description("正常显示时字体图标"), Category("SunnyUI")]
@ -228,11 +228,17 @@ namespace Sunny.UI
{ {
_dropDownStyle = value; _dropDownStyle = value;
edit.Visible = value == UIDropDownStyle.DropDown; edit.Visible = value == UIDropDownStyle.DropDown;
DropDownStyleChanged();
Invalidate(); Invalidate();
} }
} }
} }
protected virtual void DropDownStyleChanged()
{
}
public event EventHandler ButtonClick; public event EventHandler ButtonClick;
protected readonly UIEdit edit = new UIEdit(); protected readonly UIEdit edit = new UIEdit();

View File

@ -30,10 +30,6 @@
{ {
this.SuspendLayout(); this.SuspendLayout();
// //
// edit
//
this.edit.KeyDown += new System.Windows.Forms.KeyEventHandler(this.edit_KeyDown);
//
// UIComboBox // UIComboBox
// //
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;

View File

@ -24,6 +24,7 @@
* 2021-08-15: V3.0.6 * 2021-08-15: V3.0.6
* 2022-01-16: V3.1.0 * 2022-01-16: V3.1.0
* 2022-04-13: V3.1.3 Text自动选中SelectIndex * 2022-04-13: V3.1.3 Text自动选中SelectIndex
* 2022-04-15: V3.1.3
******************************************************************************/ ******************************************************************************/
using System; using System;
@ -51,20 +52,130 @@ namespace Sunny.UI
ListBox.SelectedValueChanged += ListBox_SelectedValueChanged; ListBox.SelectedValueChanged += ListBox_SelectedValueChanged;
ListBox.ItemsClear += ListBox_ItemsClear; ListBox.ItemsClear += ListBox_ItemsClear;
ListBox.ItemsRemove += ListBox_ItemsRemove; ListBox.ItemsRemove += ListBox_ItemsRemove;
edit.TextChanged += Edit_TextChanged; edit.TextChanged += Edit_TextChanged;
edit.KeyDown += Edit_KeyDown;
DropDownWidth = 150; DropDownWidth = 150;
fullControlSelect = true; fullControlSelect = true;
} }
private void ShowDropDownFilter()
{
FilterItemForm.AutoClose = false;
if (!FilterItemForm.Visible)
{
FilterItemForm.Show(this, new Size(DropDownWidth < Width ? Width : DropDownWidth, CalcItemFormHeight()));
edit.Focus();
}
}
private void Edit_KeyDown(object sender, KeyEventArgs e)
{
if (ShowFilter)
{
int cnt = filterForm.ListBox.Items.Count;
int idx = filterForm.ListBox.SelectedIndex;
if (e.KeyCode == Keys.Down || e.KeyCode == Keys.Up)
{
ShowDropDownFilter();
if (cnt > 0)
{
if (e.KeyCode == Keys.Down)
{
if (idx < cnt - 1)
filterForm.ListBox.SelectedIndex++;
}
if (e.KeyCode == Keys.Up)
{
if (idx > 0)
filterForm.ListBox.SelectedIndex--;
}
}
}
else if (e.KeyCode == Keys.Escape)
{
FilterItemForm.Close();
}
else if (e.KeyCode == Keys.Return)
{
if (FilterItemForm.Visible)
{
if (cnt > 0 && idx >= 0 && idx < cnt)
{
SelectTextChange = true;
Text = filterForm.ListBox.GetItemText(filterForm.ListBox.Items[idx]);
edit.SelectionStart = Text.Length;
SelectedValueChanged?.Invoke(this, EventArgs.Empty);
SelectTextChange = false;
}
FilterItemForm.Close();
}
else
{
ShowDropDownFilter();
}
}
else
{
base.OnKeyDown(e);
}
}
else
{
if (e.KeyCode == Keys.Enter)
{
ShowDropDown();
}
else if (e.KeyCode == Keys.Escape)
{
ItemForm.Close();
}
else
{
base.OnKeyDown(e);
}
}
}
private bool showFilter;
[DefaultValue(false)]
[Description("显示过滤"), Category("SunnyUI")]
public bool ShowFilter
{
get => showFilter;
set
{
showFilter = value;
if (value)
{
DropDownStyle = UIDropDownStyle.DropDown;
}
}
}
[DefaultValue(false)]
[Description("过滤显示最大条目数"), Category("SunnyUI")]
public int FilterMaxCount { get; set; } = 50;
protected override void DropDownStyleChanged()
{
if (DropDownStyle == UIDropDownStyle.DropDownList)
{
showFilter = false;
}
}
CurrencyManager dataManager;
private void InitStrings() private void InitStrings()
{ {
if (DropDownStyle == UIDropDownStyle.DropDown && DataSource != null && DisplayMember.IsValid()) if (DropDownStyle == UIDropDownStyle.DropDown && DataSource != null && DisplayMember.IsValid())
{ {
strings.Clear(); dataManager = (CurrencyManager)BindingContext[DataSource, new BindingMemberInfo(DisplayMember).BindingPath];
for (int i = 0; i < Items.Count; i++)
{
strings.Add(GetItemText(Items[i]));
}
} }
} }
@ -120,15 +231,64 @@ namespace Sunny.UI
private void Edit_TextChanged(object sender, EventArgs e) private void Edit_TextChanged(object sender, EventArgs e)
{ {
TextChanged?.Invoke(this, e); TextChanged?.Invoke(this, e);
if (Text.IsValid() && DropDownStyle == UIDropDownStyle.DropDown && !SelectTextChange) if (DropDownStyle == UIDropDownStyle.DropDownList) return;
if (!ShowFilter)
{ {
if (DataSource == null) if (SelectTextChange) return;
if (Text.IsValid())
{ {
SelectedIndex = Items.IndexOf(Text); ListBox.ListBox.Text = Text;
} }
else else
{ {
SelectedIndex = strings.IndexOf(Text); SelectTextChange = true;
SelectedIndex = -1;
edit.Text = "";
SelectTextChange = false;
}
}
else
{
if (edit.Focused && Text.IsValid())
{
ShowDropDownFilter();
}
filterForm.ListBox.Items.Clear();
if (Text.IsValid())
{
if (DataSource == null)
{
foreach (var item in Items)
{
if (item.ToString().Contains(Text))
{
filterForm.ListBox.Items.Add(item.ToString());
if (filterForm.ListBox.Items.Count > FilterMaxCount) break;
}
}
}
else
{
if (dataManager != null)
{
List<object> list = new List<object>();
for (int i = 0; i < Items.Count; i++)
{
if (GetItemText(dataManager.List[i]).ToString().Contains(Text))
{
list.Add(dataManager.List[i]);
if (list.Count > FilterMaxCount) break;
}
}
foreach (var item in list)
{
filterForm.ListBox.Items.Add(GetItemText(item));
}
}
}
} }
} }
} }
@ -160,7 +320,7 @@ namespace Sunny.UI
private void Box_SelectedIndexChanged(object sender, EventArgs e) private void Box_SelectedIndexChanged(object sender, EventArgs e)
{ {
SelectTextChange = true; SelectTextChange = true;
if (ListBox.SelectedItem != null) if (ListBox.SelectedItem != null && !ShowFilter)
Text = ListBox.GetItemText(ListBox.SelectedItem); Text = ListBox.GetItemText(ListBox.SelectedItem);
SelectTextChange = false; SelectTextChange = false;
SelectedIndexChanged?.Invoke(this, e); SelectedIndexChanged?.Invoke(this, e);
@ -178,17 +338,44 @@ namespace Sunny.UI
protected override void ItemForm_ValueChanged(object sender, object value) protected override void ItemForm_ValueChanged(object sender, object value)
{ {
//if (SelectedIndex != ListBox.SelectedIndex)
//{
// SelectedIndex = ListBox.SelectedIndex;
// //Box_SelectedIndexChanged(null, null);
// Invalidate();
//}
Invalidate(); Invalidate();
} }
private readonly UIComboBoxItem dropForm = new UIComboBoxItem(); private readonly UIComboBoxItem dropForm = new UIComboBoxItem();
private readonly UIComboBoxItem filterForm = new UIComboBoxItem();
private UIDropDown filterItemForm;
private UIDropDown FilterItemForm
{
get
{
if (filterItemForm == null)
{
filterItemForm = new UIDropDown(filterForm);
if (filterItemForm != null)
{
//filterItemForm.ValueChanged += FilterItemForm_ValueChanged;
filterItemForm.VisibleChanged += FilterItemForm_VisibleChanged;
//filterItemForm.Closed += FilterItemForm_Closed;
}
}
return filterItemForm;
}
}
private void FilterItemForm_VisibleChanged(object sender, EventArgs e)
{
dropSymbol = SymbolNormal;
if (filterItemForm.Visible)
{
dropSymbol = SymbolDropDown;
}
Invalidate();
}
protected override void CreateInstance() protected override void CreateInstance()
{ {
@ -206,6 +393,11 @@ namespace Sunny.UI
get => dropForm.ListBox; get => dropForm.ListBox;
} }
private ListBox FilterListBox
{
get => dropForm.ListBox.ListBox;
}
[DefaultValue(25)] [DefaultValue(25)]
[Description("列表项高度"), Category("SunnyUI")] [Description("列表项高度"), Category("SunnyUI")]
public int ItemHeight public int ItemHeight
@ -224,6 +416,11 @@ namespace Sunny.UI
{ {
ListBox.Font = Font; ListBox.Font = Font;
} }
if (filterForm != null)
{
filterForm.ListBox.Font = Font;
}
} }
public void ShowDropDown() public void ShowDropDown()
@ -231,13 +428,25 @@ namespace Sunny.UI
UIComboBox_ButtonClick(this, EventArgs.Empty); UIComboBox_ButtonClick(this, EventArgs.Empty);
} }
List<string> strings = new List<string>();
private void UIComboBox_ButtonClick(object sender, EventArgs e) private void UIComboBox_ButtonClick(object sender, EventArgs e)
{ {
if (Items.Count > 0) if (!ShowFilter)
{ {
ItemForm.Show(this, new Size(DropDownWidth < Width ? Width : DropDownWidth, CalcItemFormHeight())); if (Items.Count > 0)
{
ItemForm.Show(this, new Size(DropDownWidth < Width ? Width : DropDownWidth, CalcItemFormHeight()));
}
}
else
{
if (FilterItemForm.Visible)
{
FilterItemForm.Close();
}
else
{
ShowDropDownFilter();
}
} }
} }
@ -355,26 +564,22 @@ namespace Sunny.UI
] ]
public object SelectedValue public object SelectedValue
{ {
get => ListBox.SelectedValue; get => ShowFilter ? FilterListBox.SelectedValue : ListBox.SelectedValue;
set => ListBox.SelectedValue = value; set
{
if (!ShowFilter)
ListBox.SelectedValue = value;
}
} }
public string GetItemText(object item) public string GetItemText(object item)
{ {
return ListBox.GetItemText(item); return ShowFilter ? FilterListBox.GetItemText(item) : ListBox.GetItemText(item);
} }
private void UIComboBox_KeyDown(object sender, KeyEventArgs e) private void UIComboBox_KeyDown(object sender, KeyEventArgs e)
{ {
if (e.KeyCode == Keys.Enter) if (e.KeyCode == Keys.Enter && !ShowFilter)
{
ShowDropDown();
}
}
private void edit_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{ {
ShowDropDown(); ShowDropDown();
} }