我想免费输入组合框。当我停止输入时,我有一个延迟的任务,用一些输入相关的结果填充组合框项目。问题是我的输入被列表中的第一项覆盖。有没有办法保持我的意见?
我的示例代码如下:
public void PopulateCombo(JObject result)
{
Debug.WriteLine("Thread id: " + Thread.CurrentThread.ManagedThreadId);
cbSearch.Items.Clear();
if (result.Value<bool>("success") == true)
{
JArray arr = result.Value<JArray>("data");
for (int i = 0; i < arr.Count; i++)
{
JToken item = arr[i];
cbSearch.Items.Add(new ComboBoxItem( item.Value<string>("name"), item.Value<string>("_id")));
}
cbSearch.DroppedDown = true;
}
}
于23.06编辑
我举了一个我真正想要做的例子。
所有这些都已实现,但在步骤4中,当我使用上述函数填充组合框时,组合的文本从“ja”更改为列表的第一个匹配项。 (示例中的安东贾米森)。我几乎可以肯定,实现这种行为有一个简单的选择,但我不确定它是否在C#中。
评论:
答案 0 :(得分:1)
我没有你谈到的问题。编辑框中的文本始终保持不变。 我正在使用VS2008,但标准的ComboBox重命名为cbSearch并捕获其事件(以及表单的show事件)。 休息很好。
看起来像一个很好的任务,所以我做到了。 我也恢复了选择,虽然你可以看到一些闪烁。
最困难的是同步 - 所以我找到了一个简单而不太难看的解决方案。
尽管如此,我没有做任何与你不同的事情......也许你再次开始使用空白的ComobBox,也许你改了一些默认参数。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void cbSearch_TextUpdate(object sender, EventArgs e)
{
lastUpdate = DateTime.Now;
allowUpdate = true;
}
DateTime lastUpdate = DateTime.Now;
volatile bool allowUpdate = false;
private void BoxUpdate()
{
while (true)
{
Thread.Sleep(250);
if (allowUpdate)
{
var diff = DateTime.Now - lastUpdate;
if (diff.TotalMilliseconds > 1500)
{
allowUpdate = false;
this.InvokeEx(x =>
{
if (x.cbSearch.Text.Length > 0)
{
x.PopulateCombo(cbSearch.Text);
}
});
}
}
}
}
public void PopulateCombo(string text)
{
int sStart = cbSearch.SelectionStart;
int sLen = cbSearch.SelectionLength;
List<string> cbItems = new List<string>();
for (int i = 0; i < 3; ++i)
for (int j = 0; j < 3; ++j)
cbItems.Add(i + text + j);
cbSearch.Items.Clear();
{
for (int i = 0; i < cbItems.Count; i++)
{
cbSearch.Items.Add(cbItems[i]);
}
cbSearch.DroppedDown = true;
}
cbSearch.SelectionStart = sStart;
cbSearch.SelectionLength = sLen;
}
private void Form1_Shown(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(x =>
{
BoxUpdate();
});
}
}
public static class ISynchronizeInvokeExtensions
{
public static void InvokeEx<T>(this T @this, Action<T> action)
where T : System.ComponentModel.ISynchronizeInvoke
{
if (@this.InvokeRequired)
{
@this.Invoke(action, new object[] { @this });
}
else
{
action(@this);
}
}
}
}
答案 1 :(得分:0)
通过评论1 +一些调整的提示来管理同样的任务。这是我完成工作的最终代码:
private void cbSearch_TextUpdate(object sender, EventArgs e)
{
timer1.Stop();
timer1.Dispose();
timer1 = null;
timer1 = new System.Windows.Forms.Timer();
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Interval = 1000;
timer1.Start();
}
delegate void MethodDelegate(JObject result);
void timer1_Tick(object sender, EventArgs e)
{
timer1.Stop();
Debug.WriteLine(this.cbSearch.Text);
Debug.WriteLine("Thread id: " + Thread.CurrentThread.ManagedThreadId);
Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters["query"] = this.cbSearch.Text ?? "";
this.session.rpc["advanced_search"].execAsync(parameters, results =>
{
this.BeginInvoke(new MethodDelegate(PopulateCombo), new object[] {results.GetResult()});
});
}
public void PopulateCombo(JObject result)
{
Debug.WriteLine("Thread id: " + Thread.CurrentThread.ManagedThreadId);
this.selectedPatientId = "";
string text = cbSearch.Text;
cbSearch.DroppedDown = false;
cbSearch.Items.Clear();
if (result.Value<bool>("success") == true)
{
JArray arr = result.Value<JArray>("data");
for (int i = 0; i < arr.Count; i++)
{
JToken item = arr[i];
cbSearch.Items.Add(new ComboBoxItem( item.Value<string>("name"), item.Value<string>("_id")));
}
try
{
this.cbSearch.TextUpdate -= new System.EventHandler(this.cbSearch_TextUpdate);
cbSearch.DroppedDown = true;
cbSearch.Text = text;
cbSearch.Select(cbSearch.Text.Length, 0);
}
finally {
this.cbSearch.TextUpdate += new System.EventHandler(this.cbSearch_TextUpdate);
}
}
}