ストアド プロシージャを使用して、Sql Server 上の非常に大きなテーブルでアドレスを検索できるコンボボックスのコードを作成しました (エンティティ フレームワークを使用しています)。ストアド プロシージャは 10 件のヒットを返し、コードはコンボボックスに検索結果を入力します。これを行うために、私は BackgroundWorker を使用しています。
しかし、ここで大きな問題が発生しました: - コンボボックスには検索結果が表示されますが、常に最初の項目が選択されています。文字だけを入力しても、テキスト全体が選択されます。
その後、住所の検索は機能しなくなりました。これらの 10 件の結果のみを検索しますが、これを解決する方法がわかりません。ここに問題を引き起こす私のコード全体があります:
public String searchedItem = ""; public delegate void DelegateUpdateComboboxSelection(ComboBox myCombo,string value,int count); BackgroundWorker m_bgworker = new BackgroundWorker(); static AutoResetEvent resetWorker = new AutoResetEvent(false); m_bgworker.WorkerSupportsCancellation = true; m_bgworker.DoWork += new DoWorkEventHandler(FillComboboxBindingList); m_bgworker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(m_bgworker_RunWorkerCompleted); BindingList<spIskalnikNaslovi_Result1> m_addresses = new BindingList<SP_Result1>(); void m_bgworker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { int count = (int)((object[])e.Result)[0]; string value = (string)((object[])e.Result)[1]; ComboBox myCombo = (ComboBox)((object[])e.Result)[2]; DelegateUpdateComboboxSelection ndelegate = new DelegateUpdateComboboxSelection(UpdateComboSelection); if (this.InvokeRequired) { Invoke(ndelegate, new object[] {myCombo, value, count}); return; } else { UpdateComboSelection(myCombo, value, count); return; } } private void UpdateComboSelection(ComboBox myCombo, String value, int count) { myCombo = comboBox9; myCombo.DataSource = m_addresses; searchedItem = myCombo.Text; if (count > 0) { myCombo.SelectionStart = value.Length; myCombo.SelectionLength = searchedItem.Length - value.Length; myCombo.DroppedDown = true; } else { myCombo.DroppedDown = false; myCombo.SelectionStart = value.Length; } } public void FillComboboxBindingList(object sender, DoWorkEventArgs e) { if (m_bgworker.CancellationPending) { resetWorker.Set(); e.Cancel = true; return; } else { string value = (String)((Object[])e.Argument)[0]; List<SP_Result1> result; result = _vsebina.SP_searcher(value).ToList<SP_Result1>(); m_addresses = new BindingList<SP_Result1>(); foreach (SP_Result1 rez in result) { if (m_addresses.Contains(rez)) { continue; } else { m_addresses.Add(rez); } } foreach (SP_Result1 r in m_addresses.ToArray()) { if (!result.Contains(r)) { m_addresses.Remove(r); } } e.Result = new object[] { rezultat.Count, vrednost, null }; return; } } private void comboBox9_KeyUp(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Back) { int searchStart = comboBox9.SelectionStart; if (searchStart > 0) { searchStart--; if (searchStart == 0) { comboBox9.Text = ""; } else { comboBox9.Text = comboBox9.Text.Substring(0, searchStart + 1); } } else { searchStart = 0; } e.Handled = true; } } private void comboBox9_Enter(object sender, EventArgs e) { comboBox9.SelectionStart = 0; comboBox9.SelectionLength = 0; } private void comboBox9_Click(object sender, EventArgs e) { comboBox9.Text = ""; } private void comboBox9_KeyPress(object sender, KeyPressEventArgs e) { Search(); } public void Search() { if (comboBox9.Text.Length < 4) { return; } else { if (m_bgworker.IsBusy) { m_bgworker.CancelAsync(); m_bgworker = new BackgroundWorker(); m_bgworker.WorkerSupportsCancellation = true; m_bgworker.DoWork += new DoWorkEventHandler(FillComboboxBindingList); m_bgworker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(m_bgworker_RunWorkerCompleted); } m_bgworker.RunWorkerAsync(new object[] { comboBox9.Text, comboBox9 }); } }
多分誰かが私を啓発することができます、私が間違っていること。BackgroundWorker を使用するのはこれが初めてです。アドレスを含む私のデータテーブルは非常に大きい(100万レコード)ため、他の方法でコンボボックスを使用して「入力時に検索」を実現する方法がわかりません。
あらゆる種類のヘルプまたはコード例を事前に感謝します。
ウラジミール
編集 1: BackGroundWorker を使用する前のコードです。機能しましたが、検索が非常に遅くなります (最大 10 秒かかる場合があります)。
private void comboBox9_TextChanged(object sender, EventArgs e)
{
if (comboBox9.Text.Length < 4)
{
return;
}
else
{
FillCombobox(comboBox9.Text, comboBox9);
}
}
public void FillCombobox(string value, ComboBox myCombo)
{
List<spIskalnikNaslovi_Result1> result;
result = _vsebina.spIskalnikNaslovi1(value).ToList();
if (result.Count() > 0)
{
myCombo.DataSource = result;
myCombo.ValueMember = "HS_MID";
myCombo.DisplayMember = "NASLOV1";
var searchedItem = myCombo.Items[0].ToString();
myCombo.SelectionStart = value.Length;
myCombo.SelectionLength = searchedItem.Length - value.Length;
myCombo.DroppedDown = true;
}
else
{
myCombo.DroppedDown = false;
myCombo.SelectionStart = value.Length;
}
return;
}
バックグラウンドワーカーなしでこれをスピードアップする方法はありますか?