为什么我的Winforms ComboBox中的自动填充会在键入时更改光标位置?

时间:2017-05-25 17:37:16

标签: c# winforms combobox outlook

我在Outlook加载项中有一个WinForms ComboBox,当用户在编辑框中键入名称时,该加载项会使用用户名填充下拉列表。当用户到达第三个字符时。此时会分配ComboBox的数据源,并且光标会跳转到编辑框的开头而不是停留在结尾处。

我想要的行为是光标停留在我输入的字符串的末尾,即使下拉列表中填充了更多数据。

我尝试使用发送密钥进行黑客攻击,但它并不总能正常工作。读取下面按键的代码位于按下的按键事件中。

private void comboBox1_KeyPress(object sender, KeyEventArgs e)
{
    var acceptableKeys = ConfigurationManager.AppSettings["AcceptableKeys"];
    if (cmbAssignedTo.Text.Length > 2 && acceptableKeys.Contains(e.KeyCode.ToString().ToUpper()) && e.Modifiers == Keys.None)
    {
        var request = RestHandler.CreateRequest(ConfigurationManager.AppSettings["ContactsSearchResource"] + cmbAssignedTo.Text.Trim(), Method.GET);

        var response = RestHandler.ExecuteRequest(request, ConfigurationManager.AppSettings["myServiceURL"]);
        this.cmbAssignedTo.DataSourceChanged -= new System.EventHandler(this.cmbAssignedTo_DataSourceChanged); 
        //Assign a new data source
        DataHandler.UpdateComboboxDataSource(cmbAssignedTo, response.Content);
        this.cmbAssignedTo.DataSourceChanged += new System.EventHandler(this.cmbAssignedTo_DataSourceChanged);

    }
    e.Handled = true;
}

修改

internal static void UpdateComboboxDataSource(ComboBox cmbAssignedTo, string data)
    {
      var list = BuildAssignmentList(data);
      if ((list.Count() == 0 && cmbAssignedTo.Items.Count == 0) || list.Count() > 0)
      {
            var savedText = cmbAssignedTo.Text;
            cmbAssignedTo.DataSource = list;
            cmbAssignedTo.SelectedValue = "";
            cmbAssignedTo.Text = savedText;
            SendKeys.Send("{end}");
        }
        if (cmbAssignedTo.Items.Count > 0)
        {
            cmbAssignedTo.DroppedDown = true;
            Cursor.Current = Cursors.Default;
        }
    }

我不知道如何在不更改DataSource的情况下更新下拉列表,并且该更改似乎会导致光标跳转。我应该尝试与KeyPressed不同的事件吗?我还缺少其他一些解决方案吗?

1 个答案:

答案 0 :(得分:0)

作为另一个黑客,您可以使用ComboBox的SelectionStart属性:

int i = comboBox1.SelectionStart;
comboBox1.DataSource = new System.Collections.Generic.List<string>(){"aaaaaa", "bbbbbb", "ccccccc"};
comboBox1.SelectionStart = i;

此代码更改DataSource并保留光标位置。如果您希望光标始终位于最后 - 将SelectionStart设置为comboBox1.Text.Length

UPD:反对第一项选择&#34;你可以使用另一个黑客:

private bool cbLock = false;

private void comboBox1_TextChanged(object sender, EventArgs e)
{
  // lock is required, as this event also will occur when changing the selected index
  if (cbLock)
    return;

  cbLock = true;
  int i = comboBox1.SelectionStart;

  // store the typed string before changing DS
  string text = comboBox1.Text.Substring(0, i);

  List<string> ds = new System.Collections.Generic.List<string>() { "aaaaaa", "aaabbb", "aaacccc" };
  comboBox1.DataSource = ds;

  // select first match manually
  for (int index = 0; index < ds.Count; index++)
  {
    string s = ds[index];
    if (s.StartsWith(text))
    {
      comboBox1.SelectedIndex = index;
      break;
    }
  }

  // restore cursor position and free the lock
  comboBox1.SelectionStart = i;
  cbLock = false;
}

键入&#34; aaab&#34;它选择&#34; aaabbb&#34;字符串。