使用以下方法解决了让用户输入并自动匹配选项的问题.但是发现如果全部使用键盘输入的话.当焦点移出此单元格后此单位元格未选中任何一项.显示为空.原因见代码中...        private void dgvInfoPerson_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
        {
            if (dgvInfoPerson.CurrentCellAddress.X == dgvInfoPerson.Columns["colCboDeptNo"].Index)
            {
                cbo = e.Control as ComboBox;
                if (cbo != null)
                {
                    cbo.DropDownStyle = ComboBoxStyle.DropDown;
                    cbo.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
                }
            }
        }        private void dgvInfoPerson_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
        {
            if (dgvInfoPerson.CurrentCellAddress.X == dgvInfoPerson.Columns["colCboDeptNo"].Index)
            {
                //问题出在这里.如果你输入的是ValueMember的值的话就没问题.但你如果输入的是DisplayMember的值的话就不会选中.
                //如ValueMember="MAN" DisplayMember="管理部",如果你在此单元格输入MAN就没问题,但输入管理部就不会选中.但用户就应该是输入管理部
                  //而不是输入MAN.
                dgvInfoPerson.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = e.FormattedValue;
            }
        }已经搜过很多地方了.都没好的解决方案.还请各位有经验的前辈指点迷津.谢谢!

解决方案 »

  1.   

    刚刚发现上面的问题是因为我重写了以下方法造成的        /// <summary>
            /// 按回车时模拟按下Tab键
            /// </summary>
            /// <param name="msg"></param>
            /// <param name="keyData"></param>
            /// <returns></returns>
            protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
            {
                //判断键盘按下的键。如果等于“enter”,则send一个“{tab}”。模拟按下“tab”键,实现单元格。向下移动
                if (keyData == Keys.Enter )
                {
                    System.Windows.Forms.SendKeys.Send("{tab}");
                    return true;
                }            //继续原来base.ProcessCmdKey中的处理
                return base.ProcessCmdKey(ref msg, keyData);
            }因为按Enter就是提交修改然后才到下一行.但在这里我把Enter键取代成了Tab键.那这样的话,编辑后的数据就没提交.我要怎么在Tab键之前先提交修改好的数据呢?谢谢!
      

  2.   


                //判断键盘按下的键。如果等于“enter”,则send一个“{tab}”。模拟按下“tab”键,实现单元格。向下移动
                if (keyData == Keys.Enter )
                {
                    e.Handled = false;//加上这个试试。不行的话像下一句发送一个回车的按键消息
                    System.Windows.Forms.SendKeys.Send("{tab}");
                    return true;
                }
      

  3.   

    感谢GTX280.但是ProcessCmdKey方法中没有e这个参数.
      

  4.   

    public void ProcessHotkey(Message m) //按下设定的键时调用该函数
            {
                try
                {
                    IntPtr id = m.WParam; //IntPtr用于表示指针或句柄的平台特定类型
                    //MessageBox.Show(id.ToString());
                    string sid = id.ToString();
                    switch (sid)
                    {
                        case "100":
                            additem.ShowDialog();
                            if (additem.DialogResult == DialogResult.OK)
                            {
                                dgItemSellList[4, dgItemSellList.CurrentCell.RowIndex].Value = additem.txtnum.Text.ToString();
                            }
                            break;
                        case "200":
                            if(MessageBox.Show("确定要关闭此窗体吗?","关闭提示",MessageBoxButtons.YesNo)==DialogResult.Yes)
                            this.Close();
                            break;
                        case "300":
                            fullpay = txttotal.Text;
                            billcode = txtbillcode.Text;
                            date = txtdate.Text;
                            handle = comhandle.Text;
                            cust = comcust.Text;
                            memo = txtMemo.Text;
                            SellDetail.SellPayment sell = new SellMain.SellDetail.SellPayment();
                            if (newitemtable.Rows.Count != 0)
                            {
                                sell.ShowDialog();
                            }
                            if (sell.DialogResult == DialogResult.OK)
                            {
                                txtsfull.Text = sell.txtfullpay.Text;
                                txtspay.Text = sell.txtpay.Text;
                                txtschange.Text = sell.txtchange.Text;
                                txttotal.Text = "";
                                txtallnum.Text = "";
                                newitemtable.Clear();
                            }
                            break;
                    }
                }
                catch { }
            }        protected override void WndProc(ref Message m)//监视Windows消息
            {
                const int WM_HOTKEY = 0x0312;//如果m.Msg的值为0x0312那么表示用户按下了热键
                switch (m.Msg)
                {
                    case WM_HOTKEY:
                        ProcessHotkey(m);//按下热键时调用ProcessHotkey()函数
                        break;
                }
                base.WndProc(ref m); //将系统消息传递自父类的WndProc
            }
      

  5.   

    我截了图.也做了DEMO.请各位前辈帮忙看看.谢谢!DEMO下载http://download.csdn.net/source/903727
      

  6.   


    真正的DataGridViewComboBoxColumn 
      

  7.   

    12楼的前辈给是的 如果用户输入的不在下拉选项中时就Items.Add....不过我这里要的是..用户输入的必须在下拉选项中..所以不是我要的.谢谢!
      

  8.   

    好像用js或者Ajax可以实现!!
      

  9.   

    谢谢您的回复.我的是WINFORM的系统.谢谢!
      

  10.   

    看搂主在1楼说得,那么这样改看看呢:
          /// <summary>
            /// 按回车时模拟按下Tab键
             /// </summary>
            /// <param name="msg"></param>
            /// <param name="keyData"></param>
            /// <returns></returns>
            protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
            {
               //先执行原来base.ProcessCmdKey中的处理
               bool result = base.ProcessCmdKey(ref msg, keyData);
                //判断键盘按下的键。如果等于“enter”,则send一个“{tab}”。模拟按下“tab”键,实现单元格。向下移动
                if (keyData == Keys.Enter)
                {
                    System.Windows.Forms.SendKeys.Send("{tab}");
                    return true;
                }
               
                return result;
            }
      

  11.   

    噢,不好意思,没看清楚的问题原因。搂主设置DisplayMember和ValueMember两个属性之后,输入框中就必须输入这两个属性所包含的成员内的字符串,
    否则其他字符串被视为无效数据,所以输入列表中没有的成员,是无法显示的
      

  12.   

    而并不是由于搂主的其他代码的问题,另外DisplayMember的值运行时默认是Items属性的值
      

  13.   

    你指定了ComboBox的DisplayMember和ValueMember后,会按你输入的ValueMember来匹配的,如果输入的如果你说的管理员,它在valueMember中不存在,所以不会选中.这样的话和你设置的就矛盾了,所以应该换种思路,不一定要用comboBox,可以把当前编辑的当元格转换成TextBox,然后在TextBoxChanged里面写,至于下拉列表可以用一个listview来显示,只要把它显示在TextBox的下端坐标值即可.那样根据输入的值,listview自动找匹配的供用户自己选择
      

  14.   

    你就不会自己把ADD部分除去?                    if (Items.IndexOf(value) == -1)
                        {
                            value=Items[0];//不在下拉默认为下拉0项,我的0项一般是"OFF"\"None",可以自己做判断处理的
                        }