WinForm提示建议小工具【keydown\keyup\keypress】

--2013-11-17

最近在用VS平台做一个【WinForm提示建议小工具】,其中用到keydown\keypress事件,有些感受。

当你按下一个键盘,在keydown、keyup事件的参数keycode是不分字母大小写,只是表示按下某个键了,例如A、a是在一个键上。如果你想捕捉某个动作时 用这个事件比较合适,但是并不包含像keyascii的东西。这个东西在keypress事件的参数里e.KeyChar,而在keypress事件里是不捕捉control、shift、alt等控制键。因此,这个时候如果想把按键发送到另外一个位置,使用

private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
        {
            //当按向回车
            if (e.KeyCode == Keys.Enter)
            {
                dataGridView1_DoubleClick(sender, e);
            }
            //当按向左右箭头
//            else if (e.KeyCode==Keys.Left|| e.KeyCode==Keys.Right)
//            {
//                _listenerControl.Focus();
//            }
            //当按向下箭头
            else if (e.KeyCode == Keys.Down)
            {
                if (dataGridView1.CurrentRow != null && dataGridView1.CurrentRow.Index == dataGridView1.Rows.Count - 1 && dataGridView1.CurrentRow.Index != 0)
                {
                    e.SuppressKeyPress = true;
                    dataGridView1.CurrentCell = dataGridView1.Rows[0].Cells[0];
                }
            }
            //当按向上箭头
            else if (e.KeyCode == Keys.Up)
            {
                if (dataGridView1.CurrentRow != null && dataGridView1.CurrentRow.Index == 0 && dataGridView1.CurrentRow.Index != dataGridView1.Rows.Count - 1)
                {
                    e.SuppressKeyPress = true;
                    dataGridView1.CurrentCell = dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells[0];
                }
            }
            //否则输入框获取焦点,并将按下的字符传递
            else
            {
                _listenerControl.Focus();
            }
        }
private void dataGridView1_KeyPress(object sender, KeyPressEventArgs e)
        {
            SendKeys.Send(e.KeyChar.ToString(CultureInfo.InvariantCulture));
        }
--2013-11-29

还有就是做这个小工具会遇到一些问题,SQLServer的压力测试,因为在TextChanged就会从数据库检索数据,按照这种方式每当键入一个字符就会从sqlserver检索,尽管可以建立复合索引,但这种压力的检索速度还是觉得太大了。我也做了测试,看上去服务器的sqlserver没有明显的压力。

但是,如果指示纯粹的测试,可以按住某个键不放,这速度太快了!向服务器申请数据的速度也太快了,因此,考虑应该以时间段为单位,而不应该以TextChanged为单位,比如300ms向服务器申请一次数据,如果TextChanged那么就申请,如果Text没有change就不必申请数据了。

考虑到这种方式,就可以在提示的小工具上放个timer,这个timer没必要使用现成的,用forms下的timer消息驱动即可,因为这时对时间的要求不必太严格,大概时间即可。当text发生改变就告诉timer,300ms或等不到300ms就申请数据,设置timer时间间隔即可。这样在这300ms内发生变化的text就不会频繁申请数据。以下是代码片段:

private Control _listenerControl;
        public Control ListenerControl
        {
            set
            {
                if (!Visible)
                {
                    //确定弹出位置
                    Owner = value.FindForm();
                    Show(Owner);
                    if (Owner != null)
                        Location = new Point(value.Location.X + Owner.Location.X + 8,
                                             value.Location.Y + Owner.Location.Y + 53);

                    //自动刷新事件
                    value.TextChanged += (sender, args) =>
                        {
                            _isTextChanged = true;
                        };
                    value.KeyDown += (sender, args) =>
                        {
                            //当按向下箭头
                            if (args.KeyCode == Keys.Down)
                            {
                                args.SuppressKeyPress = true;
                                dataGridView1.Focus();
                                if (dataGridView1.CurrentRow!=null && dataGridView1.CurrentRow.Index < dataGridView1.Rows.Count-1)
                                {
                                    dataGridView1.CurrentCell = dataGridView1.Rows[dataGridView1.CurrentRow.Index + 1].Cells[0];
                                }
                                else if (dataGridView1.CurrentRow != null && dataGridView1.CurrentRow.Index == dataGridView1.Rows.Count - 1 && dataGridView1.CurrentRow.Index != 0)
                                {
                                    dataGridView1.CurrentCell = dataGridView1.Rows[0].Cells[0];
                                }
                            }
                            //当按向上箭头
                            else if (args.KeyCode == Keys.Up)
                            {
                                args.SuppressKeyPress = true;
                                dataGridView1.Focus();
                                if (dataGridView1.CurrentRow != null && dataGridView1.CurrentRow.Index != 0)
                                {
                                    dataGridView1.CurrentCell = dataGridView1.Rows[dataGridView1.CurrentRow.Index - 1].Cells[0];
                                }
                                else if (dataGridView1.CurrentRow != null && dataGridView1.CurrentRow.Index == 0 && dataGridView1.CurrentRow.Index != dataGridView1.Rows.Count - 1)
                                {
                                    dataGridView1.CurrentCell = dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells[0];
                                }
                            }
                            //当按回车
                            else if (args.KeyCode == Keys.Enter && dataGridView1.Rows.Count > 0)
                            {
                                dataGridView1_DoubleClick(sender, args);
                            }
                        };
                    value.Leave += (sender, args) => Close();

                    //首次刷新
                    FilterValue = value.Text;
                    Refresh();
                    value.Focus();
                    _listenerControl = value;
                }
            }
            get { return _listenerControl; }
        }
private void timer1_Tick(object sender, EventArgs e)
        {
            Location = new Point(_listenerControl.Location.X + Owner.Location.X + 8,
                                 _listenerControl.Location.Y + Owner.Location.Y + 53);
            if (_isTextChanged)
            {
                _isTextChanged = false;
                timer1.Enabled = false;
                FilterValue = _listenerControl.Text;
                Refresh();
                timer1.Enabled = true;
            }
        }

 

 

 
 
 

                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值