mirror of
https://github.com/netchx/netch.git
synced 2026-04-21 21:19:52 +08:00
Rename NetchLib to SearchComboBox
This commit is contained in:
179
SearchComboBox/SearchComboBox.cs
Normal file
179
SearchComboBox/SearchComboBox.cs
Normal file
@@ -0,0 +1,179 @@
|
||||
using System.Linq;
|
||||
|
||||
namespace System.Windows.Forms
|
||||
{
|
||||
[System.ComponentModel.DesignerCategory(@"Code")]
|
||||
public class SearchComboBox : ComboBox
|
||||
{
|
||||
public SearchComboBox()
|
||||
{
|
||||
AutoCompleteMode = AutoCompleteMode.Suggest;
|
||||
}
|
||||
|
||||
|
||||
private string prevKeyword;
|
||||
|
||||
private string Keyword
|
||||
{
|
||||
get => _keyword;
|
||||
set
|
||||
{
|
||||
prevKeyword = _keyword;
|
||||
if (value == null)
|
||||
{
|
||||
_keyword = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_keyword == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_keyword = value;
|
||||
ReevaluateCompletionList();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnTextChanged(EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(Text))
|
||||
{
|
||||
if (!IsOriginalItems)
|
||||
ResetCompletionList();
|
||||
Keyword = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (AutoFillTag.All(o => o.ToString() != Text))
|
||||
{
|
||||
Keyword = Text;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
base.OnTextChanged(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private object[] AutoFillTag
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Tag == null)
|
||||
{
|
||||
Tag = Items.Cast<object>().ToArray();
|
||||
}
|
||||
|
||||
return (object[]) Tag;
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsOriginalItems => Items.Count == AutoFillTag.Length;
|
||||
|
||||
public void ResetCompletionList()
|
||||
{
|
||||
Keyword = null;
|
||||
try
|
||||
{
|
||||
SuspendLayout();
|
||||
|
||||
if (IsOriginalItems)
|
||||
return;
|
||||
|
||||
Items.Clear();
|
||||
Items.AddRange(AutoFillTag);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ResumeLayout(true);
|
||||
}
|
||||
}
|
||||
|
||||
private static int findFirstDifIndex(string s1, string s2)
|
||||
{
|
||||
for (var i = 0; i < Math.Min(s1.Length, s2.Length); i++)
|
||||
if (s1[i] != s2[i])
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private object[] _newList;
|
||||
private string _keyword;
|
||||
|
||||
private void ReevaluateCompletionList()
|
||||
{
|
||||
SuspendLayout();
|
||||
var keyword = Keyword.ToLowerInvariant().Trim();
|
||||
|
||||
var selectionStart = SelectionStart;
|
||||
if (selectionStart == Text.Length)
|
||||
{
|
||||
selectionStart = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
selectionStart = findFirstDifIndex(prevKeyword, Keyword);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var originalList = AutoFillTag;
|
||||
if (originalList == null)
|
||||
{
|
||||
Tag = originalList = Items.Cast<object>().ToArray();
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(Keyword))
|
||||
{
|
||||
ResetCompletionList();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
_newList = originalList.Where(x => x.ToString().ToLowerInvariant().Contains(keyword)).ToArray();
|
||||
}
|
||||
|
||||
if (_newList.Any())
|
||||
{
|
||||
Items.Clear();
|
||||
Items.AddRange(_newList.ToArray());
|
||||
|
||||
if (!DroppedDown)
|
||||
{
|
||||
DroppedDown = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO 预期下拉框高度变长则重新打开下拉框
|
||||
}
|
||||
|
||||
Cursor.Current = Cursors.Default;
|
||||
}
|
||||
else
|
||||
{
|
||||
DroppedDown = false;
|
||||
Items.Clear();
|
||||
}
|
||||
|
||||
if (selectionStart == -1)
|
||||
{
|
||||
Select(Text.Length, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Select(selectionStart + 1, 0);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
ResumeLayout(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user