2017-05-25 84 views
0

我在Outlook加载项中有一个WinForms组合框,当用户在编辑框中键入名称时,该组件框会填充用户名下拉列表。当用户到达第三个字符时。此时ComboBox的数据源被分配,并且光标跳到编辑框的开头,而不是停留在最后。为什么我的WinForms组合框中的自动完成在键入时更改光标位置?

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

我试过用发送密钥破解这个,但它并不总是有效。读取以下按键的代码位于按键事件中。

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; 
     } 
    } 

我不知道怎样才能更新下拉不改变数据源和变化似乎导致光标跳。我应该尝试不同于KeyPressed的事件吗?有没有其他解决方案我失踪?

+0

将“cmbAssignedTo_DataSourceChanged”的代码添加到问题 –

+0

添加了实际更改了数据源的代码。事件方法@ S.Petrosov请求实际上是一个无操作。我将从KeyPressed事件中删除它。 – Blanthor

+1

尝试验证延迟技巧,我发现: https://stackoverflow.com/questions/8001450/c-sharp-wait-for-user-to-finish-typing-in-a-text-box Regards, Tim – Tim

回答

0

作为另一个黑客可以用组合框的SelectionStart性能发挥:

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

这段代码改变了数据源,并保留光标位置。如果您希望光标总是处于末尾 - 设置为SelectionStartcomboBox1.Text.Length

UPD:要对“第一项选择”打你可以使用另一个黑客:

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; 
} 

当键入“AAAB”它选择了“AAABBB”字符串。

+0

这很接近,但它一直移动到自动完成中第一个选项的末尾。与前四个字符匹配的其他选择将被忽略。例如,如果我在下拉列表中选择Mike A和Mike B,它会自动选择Mike A.但是我希望能够选择Mike B. – Blanthor