一个自动完成插件的类(TextBox 版)

弄着玩.还蛮有意思的..应该还有很多BUG跟用起来不舒服的地方吧..希望路过的朋友给提下意见.谢谢...

IMYansSuggest

/// <summary>
/// for TextBox 
/// </summary>
public class IMYansSuggest<TEntity> where TEntity : class
{
    
#region events

    
public delegate void OnConfirmHandler(TEntity entity);
    
public event OnConfirmHandler OnConfirm;

    
#endregion

    
#region private controls

    TextBox iwin;
    Panel panel;
    DataGridView dgv;

    
#endregion
        


    List
<TEntity> lstData;
    
public IMYansSuggest(TextBox IWin) {
        iwin 
= IWin;
        bindWin();
    }

    
public IMYansSuggest(TextBox IWin, List<TEntity> lstdata) {
        iwin 
= IWin;
        lstData 
= lstdata;
        bindWin();
        InitializeComponent();
    }
         
    
/// <summary>
    
/// 设置数据源
    
/// </summary>
    
/// <param name="lstdata"></param>
    public void SetCustomDataSource(List<TEntity> lstdata) {
        lstData 
= lstdata;
        InitializeComponent();
    }

    List
<string> showColumns = new List<string>();
    
/// <summary>
    
/// 设置显示字段
    
/// </summary>
    
/// <param name="column">显示字段</param>
    public void SetShowColumns(params string[] column) {
        showColumns 
= column.ToList();
    }

    
/// <summary>
    
/// 获取显示字段
    
/// </summary>
    
/// <returns></returns>
    public List<string> GetShowColumns() {
        
if (showColumns.Count > 0)
            
return showColumns;
        
return typeof(TEntity).GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public).Select(Y => Y.Name).ToList();
    }

    
string enterColumn = string.Empty;
    
/// <summary>
    
/// 设置填入文本信息
    
/// </summary>
    
/// <param name="columnName"></param>
    public void SetEnterColumnName(string columnName) {
        enterColumn 
= columnName;
    }

    
void InitializeComponent() {
        
if (null == dgv) {
            dgv 
= new DataGridView();
            dgv.AutoGenerateColumns 
= false;
            panel 
= new Panel();
            panel.Controls.Add(dgv);
            dgv.Dock 
= DockStyle.Fill;
            panel.Visible 
= false;
            iwin.Parent.Controls.Add(panel);

            panel.Top 
= iwin.Top + iwin.Height;
            panel.Left 
= iwin.Left;

            
foreach (var v in GetShowColumns()) {
                var dc 
= new DataGridViewTextBoxColumn();
                dc.DataPropertyName 
= v;
                dc.Name 
= v;
                dgv.Columns.Add(dc);
            }
            dgv.DataSource 
= lstData;


            panel.BringToFront();
            dgv.RowHeadersVisible 
= false;
            dgv.RowTemplate.Height 
= 18;
            dgv.ColumnHeadersVisible 
= false;
            dgv.AllowUserToDeleteRows 
= false;
            dgv.AllowUserToAddRows 
= false;
            dgv.AllowUserToResizeColumns 
= false;
            dgv.AllowUserToResizeRows 
= false

            dgv.SelectionMode 
= DataGridViewSelectionMode.FullRowSelect;
            dgv.MultiSelect 
= false;
            dgv.TabStop 
= false
            panel.HorizontalScroll.Enabled 
= false;
            panel.Width 
= dgv.Columns.Cast<DataGridViewColumn>().Sum(Y => Y.Width) + 20;

            dgv.LostFocus 
+= new EventHandler(IWin_LostFocus);
            dgv.CellDoubleClick 
+= new DataGridViewCellEventHandler(dgv_CellDoubleClick);
        }
    }

    
void dgv_CellDoubleClick(object sender, DataGridViewCellEventArgs e) {
        
if (e.RowIndex > -1) {
            SetIWinValue((TEntity)dgv.CurrentRow.DataBoundItem);
            iwin.SelectAll();
        }
    }

    
void bindWin() {
        iwin.TextChanged 
+= new EventHandler(IWin_TextChanged);
        iwin.LostFocus 
+= new EventHandler(IWin_LostFocus);
        iwin.GotFocus 
+= new EventHandler(iwin_GotFocus);
        iwin.MouseWheel 
+= new MouseEventHandler(iwin_MouseWheel);
        iwin.KeyDown 
+= new KeyEventHandler(iwin_KeyDown);
    }

    
void iwin_KeyDown(object sender, KeyEventArgs e) {
        
if (e.KeyCode == Keys.Up) {
            scrollUp();
        }
        
else if (e.KeyCode == Keys.Down) {
            scrollDown();
        }
        
else if (e.KeyCode == Keys.Enter) {
            
if (null != dgv.CurrentRow) {
                SetIWinValue((TEntity)dgv.CurrentRow.DataBoundItem);
            }
        }
    }

    
public string GetShowColumn() {
        
if (enterColumn.Length > 0)
            
return enterColumn;
        
return typeof(TEntity).GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public)[0].Name;
    }

    
void SetIWinValue(TEntity entity) {
        
if (null != OnConfirm) {
            OnConfirm(entity);
        }
        
else {
            iwin.Text 
= typeof(TEntity).GetProperty(GetShowColumn()).GetValue(entity, null).ToString();
        }
    }

    
/// <summary>
    
/// 鼠标滚动
    
/// </summary>
    
/// <param name="sender"></param>
    
/// <param name="e"></param>
    void iwin_MouseWheel(object sender, MouseEventArgs e) {
        
if (e.Delta > 0) {
            scrollUp();
        }
        
else if (e.Delta < 0) {
            scrollDown();
        }
    }

    
/// <summary>
    
/// 获得焦点
    
/// </summary>
    
/// <param name="sender"></param>
    
/// <param name="e"></param>
    void iwin_GotFocus(object sender, EventArgs e) {
        
if (null != dgv) {
            panel.Visible 
= true;
        }
        iwin.SelectAll();
    }

    
/// <summary>
    
/// 失去焦点
    
/// </summary>
    
/// <param name="sender"></param>
    
/// <param name="e"></param>
    void IWin_LostFocus(object sender, EventArgs e) {
        
if (null != dgv && dgv.Visible && !dgv.Focused && !iwin.Focused) {
            panel.Visible 
= false;
        }
    }


    
void scrollUp() {
        
if (null == dgv.CurrentRow) {
            dgv.ClearSelection();
            dgv.Rows[
0].Selected = true;
            dgv.CurrentCell 
= dgv.Rows[0].Cells[0];
        }
        
else {
            var index 
= dgv.SelectedRows[0].Index;
            
if (index > 0) {
                dgv.ClearSelection();
                dgv.Rows[index 
- 1].Selected = true;
                dgv.CurrentCell 
= dgv.Rows[index - 1].Cells[0];
            }
        }
    }

    
void scrollDown() {
        
if (null == dgv.CurrentRow) {
            dgv.ClearSelection();
            dgv.Rows[
0].Selected = true;
            dgv.CurrentCell 
= dgv.Rows[0].Cells[0];
        }
        
else {
            var index 
= dgv.SelectedRows[0].Index;
            
if (index != dgv.Rows.Count - 1) {
                dgv.ClearSelection();
                dgv.Rows[index 
+ 1].Selected = true;
                dgv.CurrentCell 
= dgv.Rows[index + 1].Cells[0];
            }
        }
    }

    
/// <summary>
    
/// 文本改变
    
/// </summary>
    
/// <param name="sender"></param>
    
/// <param name="e"></param>
    void IWin_TextChanged(object sender, EventArgs e) {
        
bool isFinded = false;
        
for (int i = 0; i < dgv.Rows.Count; i++) {
            var row 
= dgv.Rows[i];
            
//                foreach (DataColumn dc in data.Columns) {
            foreach (var v in GetShowColumns()) {
                
if (row.Cells[v].Value.ToString().StartsWith(iwin.Text, true, System.Globalization.CultureInfo.InvariantCulture)) {
                    dgv.ClearSelection();
                    row.Selected 
= true;
                    dgv.CurrentCell 
= row.Cells[0];
                    isFinded 
= true;
                    
break;
                }
            }
            
if (isFinded) break;
        }
    }

}

实例化一个类出来,,请指明所用数据源的类型,,再指定一个数据源即可...

实例如下:

代码
public partial class frmMain : Form
{
    
public frmMain() {
        InitializeComponent();
    }

    
private void frmMain_Load(object sender, EventArgs e) {

        var lstPerson 
= new List<Person>();
        Random r 
= new Random();
        
for (int i = 1; i < 100; i++) {
            lstPerson.Add(
new Person {
                ID 
= i,
                Name 
= "yans" + i.ToString(),
                Age 
= r.Next(1100),
                Remark 
= "this just a remark for you."
            });
        }

        
new IMYansSuggest<Person>(textBox1, lstPerson);
    }
}

class Person
{
    
public int ID { getset; }
    
public string Name { getset; }
    
public int Age { getset; }
    
public string Remark { getset; }
}

效果图:

当然你可以自己设置要填充文本框的属性名或者是设置要显示的属性..

原文地址:https://www.cnblogs.com/yans/p/1926458.html