gpt4 book ai didi

c# - 子字符串上的 ComboBox 自动完成

转载 作者:可可西里 更新时间:2023-11-01 07:54:15 27 4
gpt4 key购买 nike

在我的一个 WinForms 应用程序中,我有一个带有组合框的窗口,供用户从中选择客户。

此列表框中的客户采用以下格式:“CustomerID - CustomerName”,例如“004540 - NorthWind Traders”

native WinForms 组合框具有内置的自动完成功能并且运行良好:问题是它只能通过从组合框列表的每个项目的字符串开头进行匹配而不是从任何地方(子字符串)开始进行匹配。

我希望我的用户能够做的是键入 CustomerID 或 CustomerName,因为高级用户熟悉大多数 CustomerID,而新员工将受益于能够键入 CustomerName 并获得自动完成功能.这意味着我实际上想从列表中寻找最佳匹配,其中输入的文本是 ComboBox 项的子字符串。

通常针对这种情况建议的解决方案是创建一个仅在用户键入时才显示的隐藏列表框,但我对此并不满意,因为它感觉像是一种快速破解并且不容易重用,并且与标准 ComboBox 控件相比,外观和行为可能不一致。

我尝试使用 DroppedDown 属性自己实现此功能以显示列表并使用 SelectedIndex 设置项目,但是当我这样做时组合框的文本框的内容被重置,而我只想要“最佳匹配” item”从 ComboBox 列表中突出显示(我需要“建议”而不是“追加”,追加模式无论如何不能真正用于子字符串匹配)。

我想一定有更好的方法吧?如果有人知道自定义/第 3 方控件这样做,我也不反对购买。

谢谢。

PS:我正在使用 .Net Framework 3.5 使用 C# 为 WinForms 编程。

最佳答案

这是 C# 版本。它有很多选项。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
this.Load += new EventHandler(this.Form1_Load);

InitializeComponent();
}

private clsCustomAutoCompleteTextbox ClsCustomAutoCompleteTextbox1 = null;

private List<string> MasterList = new List<string> ();

public void Form1_Load(object sender, System.EventArgs e) {
this.ClsCustomAutoCompleteTextbox1 = new clsCustomAutoCompleteTextbox();

this.ClsCustomAutoCompleteTextbox1.AutoCompleteFormBorder = System.Windows.Forms.FormBorderStyle.None;

this.ClsCustomAutoCompleteTextbox1.AutoCompleteList = null;
this.ClsCustomAutoCompleteTextbox1.Location = new System.Drawing.Point(27, 57);
this.ClsCustomAutoCompleteTextbox1.Name = "clsCustomAutoCompleteTextbox1";
this.ClsCustomAutoCompleteTextbox1.OnEnterSelect = true;
this.ClsCustomAutoCompleteTextbox1.SelectionMethods = clsCustomAutoCompleteTextbox.SelectOptions.OnEnterSingleClick;
this.ClsCustomAutoCompleteTextbox1.SelectTextAfterItemSelect = true;
this.ClsCustomAutoCompleteTextbox1.ShowAutoCompleteOnFocus = false;
this.ClsCustomAutoCompleteTextbox1.Size = new System.Drawing.Size(232, 20);
this.ClsCustomAutoCompleteTextbox1.TabIndex = 0;

this.Controls.Add(this.ClsCustomAutoCompleteTextbox1);

this.ClsCustomAutoCompleteTextbox1.BeforeDisplayingAutoComplete +=
new EventHandler<clsCustomAutoCompleteTextbox.clsAutoCompleteEventArgs>(BeforeDisplayingAutoComplete);

List<string> L;
L = new List<string>();
L.Add("123123 - Bob");
L.Add("534543 - Sally");
L.Add("123123 - George");
L.Add("34213 - Happy");
MasterList = L;
this.ClsCustomAutoCompleteTextbox1.AutoCompleteList = L;
}

private void BeforeDisplayingAutoComplete(object sender, clsCustomAutoCompleteTextbox.clsAutoCompleteEventArgs e) {
string Name = this.ClsCustomAutoCompleteTextbox1.Text.ToLower();
List<string> Display = new List<string> ();
foreach (string Str in MasterList) {
if ((Str.ToLower().IndexOf(Name) > -1)) {
Display.Add(Str);
}
}
e.AutoCompleteList = Display;
e.SelectedIndex = 0;
}
}
public class clsCustomAutoCompleteTextbox : TextBox
{
private bool First = true;

private object sender;

private clsAutoCompleteEventArgs e;

public List<string> test = new List<string> ();

public int Tabs = 0;

private int mSelStart;

private int mSelLength;

private List<string> myAutoCompleteList = new List<string> ();

private ListBox myLbox = new ListBox();

private Form myForm = new Form();

private Form myParentForm;

private bool DontHide = false;

private bool SuspendFocus = false;

private clsAutoCompleteEventArgs Args;

private Timer HideTimer = new Timer();

private Timer FocusTimer = new Timer();

private bool myShowAutoCompleteOnFocus;

private System.Windows.Forms.FormBorderStyle myAutoCompleteFormBorder = FormBorderStyle.None;

private bool myOnEnterSelect;

private int LastItem;

private SelectOptions mySelectionMethods = (SelectOptions.OnDoubleClick | SelectOptions.OnEnterPress);

private bool mySelectTextAfterItemSelect = true;

private List<string> value;

private int Cnt = 0;

public bool SelectTextAfterItemSelect
{
get
{
return mySelectTextAfterItemSelect;
}
set
{
mySelectTextAfterItemSelect = value;
}
}

[System.ComponentModel.Browsable(false)]
public SelectOptions SelectionMethods
{
get
{
return mySelectionMethods;
}
set
{
mySelectionMethods = value;
}
}

public bool OnEnterSelect
{
get
{
return myOnEnterSelect;
}
set
{
myOnEnterSelect = value;
}
}

public System.Windows.Forms.FormBorderStyle AutoCompleteFormBorder
{
get
{
return myAutoCompleteFormBorder;
}
set
{
myAutoCompleteFormBorder = value;
}
}

public bool ShowAutoCompleteOnFocus
{
get
{
return myShowAutoCompleteOnFocus;
}
set
{
myShowAutoCompleteOnFocus = value;
}
}

public ListBox Lbox
{
get
{
return myLbox;
}
}

public List<string> AutoCompleteList { get; set; }

public event EventHandler<clsAutoCompleteEventArgs> BeforeDisplayingAutoComplete;

public event EventHandler<clsItemSelectedEventArgs> ItemSelected;

public enum SelectOptions
{
None = 0,

OnEnterPress = 1,

OnSingleClick = 2,

OnDoubleClick = 4,

OnTabPress = 8,

OnRightArrow = 16,

OnEnterSingleClick = 3,

OnEnterSingleDoubleClicks = 7,

OnEnterDoubleClick = 5,

OnEnterTab = 9,
}

public class clsAutoCompleteEventArgs : EventArgs
{

private List<string> myAutoCompleteList;

private bool myCancel;

private int mySelectedIndex;

private List<string> value;

public int SelectedIndex
{
get
{
return mySelectedIndex;
}
set
{
mySelectedIndex = value;
}
}

public bool Cancel
{
get
{
return myCancel;
}
set
{
myCancel = value;
}
}
public List<string> AutoCompleteList { get; set; }
}

public override string SelectedText
{
get
{
return base.SelectedText;
}
set
{
base.SelectedText = value;
}
}

public override int SelectionLength
{
get
{
return base.SelectionLength;
}
set
{
base.SelectionLength = value;
}
}

public clsCustomAutoCompleteTextbox()
{
HideTimer.Tick += new EventHandler(HideTimer_Tick);
FocusTimer.Tick += new EventHandler(FocusTimer_Tick);

myLbox.Click += new EventHandler(myLbox_Click);
myLbox.DoubleClick += new EventHandler(myLbox_DoubleClick);
myLbox.GotFocus += new EventHandler(myLbox_GotFocus);
myLbox.KeyDown += new KeyEventHandler(myLbox_KeyDown);

myLbox.KeyUp += new KeyEventHandler(myLbox_KeyUp);
myLbox.LostFocus += new EventHandler(myLbox_LostFocus);
myLbox.MouseClick += new MouseEventHandler(myLbox_MouseClick);
myLbox.MouseDoubleClick += new MouseEventHandler(myLbox_MouseDoubleClick);
myLbox.MouseDown += new MouseEventHandler(myLbox_MouseDown);


this.GotFocus += new EventHandler(clsCustomAutoCompleteTextbox_GotFocus);
this.KeyDown += new KeyEventHandler(clsCustomAutoCompleteTextbox_KeyDown);
this.Leave += new EventHandler(clsCustomAutoCompleteTextbox_Leave);
this.LostFocus += new EventHandler(clsCustomAutoCompleteTextbox_LostFocus);
this.Move += new EventHandler(clsCustomAutoCompleteTextbox_Move);
this.ParentChanged += new EventHandler(clsCustomAutoCompleteTextbox_ParentChanged);


}

override protected void OnKeyUp(System.Windows.Forms.KeyEventArgs e)
{


base.OnKeyUp(e);
ShowOnChar(new string(((char)(e.KeyValue)),1));
}

private void ShowOnChar(string C)
{


if (IsPrintChar(C))
{
this.ShowAutoComplete();
}
}

private bool IsPrintChar(int C)
{


return IsPrintChar(((char)(C)));
}

private bool IsPrintChar(byte C)
{


return IsPrintChar(((char)(C)));
}

private bool IsPrintChar(char C)
{


return IsPrintChar(C.ToString());
}

private bool IsPrintChar(string C)
{

if (System.Text.RegularExpressions.Regex.IsMatch(C, "[^\\t\\n\\r\\f\\v]"))
{
return true;
}
else
{
return false;
}

}

private void clsCustomAutoCompleteTextbox_GotFocus(object sender, System.EventArgs e)
{

if ((!this.SuspendFocus
&& (this.myShowAutoCompleteOnFocus
&& (this.myForm.Visible == false))))
{
this.ShowAutoComplete();
}

}

private void clsCustomAutoCompleteTextbox_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{

if (!SelectItem(e.KeyCode, false, false))
{
if ((e.KeyCode == Keys.Up))
{
if ((myLbox.SelectedIndex > 0))
{
MoveLBox((myLbox.SelectedIndex - 1));
}
}
else if ((e.KeyCode == Keys.Down))
{
MoveLBox((myLbox.SelectedIndex + 1));
}
}

}

new void SelectAll()
{
}

private void MoveLBox(int Index)
{

try
{
if ((Index
> (myLbox.Items.Count - 1)))
{
Index = (myLbox.Items.Count - 1);
}
myLbox.SelectedIndex = Index;
}
catch
{
}

}

private void clsCustomAutoCompleteTextbox_Leave(object sender, System.EventArgs e)
{

DoHide(sender, e);

}

private void clsCustomAutoCompleteTextbox_LostFocus(object sender, System.EventArgs e)
{

DoHide(sender, e);

}

private void clsCustomAutoCompleteTextbox_Move(object sender, System.EventArgs e)
{

MoveDrop();

}

private void clsCustomAutoCompleteTextbox_ParentChanged(object sender, System.EventArgs e)
{

if (myParentForm != null) myParentForm.Deactivate -= new EventHandler(myParentForm_Deactivate);
myParentForm = GetParentForm(this);
if (myParentForm != null) myParentForm.Deactivate += new EventHandler(myParentForm_Deactivate);
}

private void HideTimer_Tick(object sender, System.EventArgs e)
{

MoveDrop();
DoHide(sender, e);
Cnt++;
if ((Cnt > 300))
{
if (!AppHasFocus(""))
{
DoHideAuto();
}
Cnt = 0;
}

}

private void myLbox_Click(object sender, System.EventArgs e)
{
}

private void myLbox_DoubleClick(object sender, System.EventArgs e)
{
}

private bool SelectItem(Keys Key, bool SingleClick)
{
return SelectItem(Key, SingleClick, false);
}

private bool SelectItem(Keys Key)
{
return SelectItem(Key, false, false);
}

private bool SelectItem(Keys Key, bool SingleClick, bool DoubleClick)
{

// Warning!!! Optional parameters not supported
// Warning!!! Optional parameters not supported
// Warning!!! Optional parameters not supported
bool DoSelect = true;
SelectOptions Meth = SelectOptions.None;
LastItem = -1;

if (((this.mySelectionMethods & SelectOptions.OnEnterPress) > 0) && (Key == Keys.Enter))
{
Meth = SelectOptions.OnEnterPress;
}
else if (((this.mySelectionMethods & SelectOptions.OnRightArrow) > 0) && Key == Keys.Right)
{
Meth = SelectOptions.OnRightArrow;
}
else if (((this.mySelectionMethods & SelectOptions.OnTabPress) > 0) && Key == Keys.Tab)
{
Meth = SelectOptions.OnTabPress;
}
else if (((this.mySelectionMethods & SelectOptions.OnSingleClick) > 0) && SingleClick)
{
Meth = SelectOptions.OnEnterPress;
}
else if (((this.mySelectionMethods & SelectOptions.OnDoubleClick) > 0) && DoubleClick)
{
Meth = SelectOptions.OnEnterPress;
}
else
{
DoSelect = false;
}

LastItem = myLbox.SelectedIndex;
if (DoSelect)
{
DoSelectItem(Meth);
}

return DoSelect;
}
public class clsItemSelectedEventArgs : EventArgs
{

private int myIndex;

private SelectOptions myMethod;

private string myItemText;

public clsItemSelectedEventArgs()
{
}

public clsItemSelectedEventArgs(int Index, SelectOptions Method, string ItemText)
{
myIndex = Index;
myMethod = Method;
myItemText = ItemText;
}

public string ItemText
{
get
{
return myItemText;
}
set
{
myItemText = value;
}
}

public SelectOptions Method
{
get
{
return myMethod;
}
set
{
myMethod = value;
}
}

public int Index
{
get
{
return myIndex;
}
set
{
myIndex = value;
}
}
}

[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();

[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern int GetWindowThreadProcessId(IntPtr hWnd, ref int ProcessID);

private bool AppHasFocus(string ExeNameWithoutExtension)
{
bool Out = false;
// Warning!!! Optional parameters not supported
int PID = 0;

if ((ExeNameWithoutExtension == ""))
{
ExeNameWithoutExtension = System.Diagnostics.Process.GetCurrentProcess().ProcessName;
}
IntPtr activeHandle = GetForegroundWindow();
GetWindowThreadProcessId(activeHandle, ref PID);
if ((PID > 0))
{
// For Each p As Process In Process.GetProcessesByName(ExeNameWithoutExtension)
if ((PID == System.Diagnostics.Process.GetCurrentProcess().Id))
{
Out = true;
}
// Next
}

return Out;
}

private void SaveSelects()
{
this.mSelStart = this.SelectionStart;
this.mSelLength = this.SelectionLength;
}

private void LoadSelects()
{
this.SelectionStart = this.mSelStart;
this.SelectionLength = this.mSelLength;
}

private void ShowAutoComplete()
{

Args = new clsAutoCompleteEventArgs();
// With...
Args.Cancel = false;
Args.AutoCompleteList = this.myAutoCompleteList;
if ((myLbox.SelectedIndex == -1))
{
Args.SelectedIndex = 0;
}
else
{
Args.SelectedIndex = myLbox.SelectedIndex;
}

if (BeforeDisplayingAutoComplete != null) BeforeDisplayingAutoComplete(this, Args);
this.myAutoCompleteList = Args.AutoCompleteList;
// If Me.myAutoCompleteList IsNot Nothing AndAlso Me.myAutoCompleteList.Count - 1 < Args.SelectedIndex Then
// Args.SelectedIndex = Me.myAutoCompleteList.Count - 1
// End If
if ((!Args.Cancel && (Args.AutoCompleteList != null) && Args.AutoCompleteList.Count > 0))
{
DoShowAuto();
}
else
{
DoHideAuto();
}

}

private void DoShowAuto()
{
SaveSelects();

myLbox.BeginUpdate();
try
{
myLbox.Items.Clear();
myLbox.Items.AddRange(this.myAutoCompleteList.ToArray());
this.MoveLBox(Args.SelectedIndex);
}
catch (Exception ex)
{
}
myLbox.EndUpdate();
myParentForm = GetParentForm(this);
if (myParentForm != null)
{
myLbox.Name = ("mmmlbox" + DateTime.Now.Millisecond);
if ((myForm.Visible == false))
{
myForm.Font = this.Font;
myLbox.Font = this.Font;
myLbox.Visible = true;
myForm.Visible = false;
myForm.ControlBox = false;
myForm.Text = "";
if (First)
{
myForm.Width = this.Width;
myForm.Height = 200;
}
First = false;
if (!myForm.Controls.Contains(myLbox))
{
myForm.Controls.Add(myLbox);
}
myForm.FormBorderStyle = FormBorderStyle.None;
myForm.ShowInTaskbar = false;
// With...
myLbox.Dock = DockStyle.Fill;
myLbox.SelectionMode = SelectionMode.One;
// Frm.Controls.Add(myLbox)
DontHide = true;
SuspendFocus = true;
myForm.TopMost = true;
myForm.FormBorderStyle = this.myAutoCompleteFormBorder;
myForm.BringToFront();
MoveDrop();
myForm.Visible = true;
myForm.Show();
MoveDrop();
HideTimer.Interval = 10;
this.Focus();
SuspendFocus = false;
HideTimer.Enabled = true;
DontHide = false;
LoadSelects();
}
}

}

void MoveDrop()
{

Point Pnt = new Point(this.Left, (this.Top
+ (this.Height + 2)));
Point ScreenPnt = this.PointToScreen(new Point(-2, this.Height));
// Dim FrmPnt As Point = Frm.PointToClient(ScreenPnt)
if (myForm != null)
{
myForm.Location = ScreenPnt;
// myForm.BringToFront()
// myForm.Focus()
// myLbox.Focus()
// Me.Focus()
}

}

void DoHide(object sender, EventArgs e)
{

HideAuto();

}

private void DFocus(int Delay)
{

// Warning!!! Optional parameters not supported
FocusTimer.Interval = Delay;
FocusTimer.Start();

}

private void DFocus()
{
DFocus(10);
}

private void DoHideAuto()
{

myForm.Hide();
HideTimer.Enabled = false;
FocusTimer.Enabled = false;

}

private void HideAuto()
{

if ((myForm.Visible && HasLostFocus()))
{
DoHideAuto();
}

}

private bool HasLostFocus()
{

bool Out = false;
if (this.myForm == null || myForm.ActiveControl != this.myLbox)
{
Out = true;
}
if (this.myParentForm == null || this.myParentForm.ActiveControl != this)
{
Out = true;
}

return Out;
}

private Form GetParentForm(Control InCon)
{

Control TopCon = FindTopParent(InCon);
Form Out = null;
if ((TopCon is Form))
{
Out = ((Form)(TopCon));
}

return Out;
}

private Control FindTopParent(Control InCon)
{

Control Out;
if ((InCon.Parent == null))
{
Out = InCon;
}
else
{
Out = FindTopParent(InCon.Parent);
}

return Out;
}

private void DoSelectItem(SelectOptions Method)
{

if (((this.myLbox.Items.Count > 0)
&& (this.myLbox.SelectedIndex > -1)))
{
string Value = this.myLbox.SelectedItem.ToString();
string Orig = this.Text;
this.Text = Value;
if (mySelectTextAfterItemSelect)
{
try
{
this.SelectionStart = Orig.Length;
this.SelectionLength = (Value.Length - Orig.Length);
}
catch (Exception ex)
{
}
}
else
{
// Me.SelectionStart = Me.Text.Length
// Me.SelectionLength = 0
}

clsItemSelectedEventArgs a;
a = new clsItemSelectedEventArgs();
a.Index = this.myLbox.SelectedIndex;
a.Method = Method;
a.ItemText = Value;

if (ItemSelected != null) ItemSelected(this, a);

//ItemSelected(this, new clsItemSelectedEventArgs(this.myLbox.SelectedIndex, Method, Value));
this.DoHideAuto();
}

}

private void myLbox_GotFocus(object sender, System.EventArgs e)
{

DFocus();

}

private void myLbox_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{

SelectItem(e.KeyCode);

}

private void ProcessKeyEvents(KeyEventArgs e)
{


if ((e.KeyCode >= Keys.A) && (e.KeyCode <= Keys.Z))
base.OnKeyUp(e);


//Keys.Back;
//Keys.Enter;
//Keys.Left;
//Keys.Right;
//Keys.Up;
//Keys.Down;
//(Keys.NumPad0 & (e.KeyCode <= Keys.NumPad9));
//(Keys.D0 & (e.KeyCode <= Keys.D9));


}

private void myLbox_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
if (IsPrintChar(e.KeyChar))
{
// Me.OnKeyPress(e)
// Call MoveDrop()
}

}

private void myLbox_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
{
if (IsPrintChar(e.KeyValue))
{
// Me.OnKeyUp(e)
// Call MoveDrop()
}

}

private void myLbox_LostFocus(object sender, System.EventArgs e)
{

DoHide(sender, e);

}

private void myLbox_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
{

// If e.Button <> Windows.Forms.MouseButtons.None Then
SelectItem(Keys.None,true);
// End If

}

private void myLbox_MouseDoubleClick(object sender, System.Windows.Forms.MouseEventArgs e)
{

// If e.Button <> Windows.Forms.MouseButtons.None Then
SelectItem(Keys.None, false, true);
// End If

}

private void myForm_Deactivate(object sender, System.EventArgs e)
{


}

private void myParentForm_Deactivate(object sender, System.EventArgs e)
{


}

private void FocusTimer_Tick(object sender, System.EventArgs e)
{

this.Focus();

}

private void myLbox_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
myLbox_MouseClick(sender, e);
}
}
}

关于c# - 子字符串上的 ComboBox 自动完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3694720/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com