2013-11-28 17 views
-1

我有一個搜索字段,用戶搜索每個輸入的字符。所以沒有搜索按鈕。問題是搜索速度很慢。我的想法是在每個鍵輸入一點後延遲搜索,所以如果用戶快速輸入搜索字符串,則不用搜索就可以進行搜索。然後執行搜索。我的代碼到目前爲止。如何搜索每一個性能更好的字符?

procedure TAgreementModuleForm.SetIsSearching(const Value: Boolean); 
begin 
    fIsSearching := Value; 
    tmrDelayKey.Enabled := Value; 
end; 

procedure TAgreementModuleForm.tmrDelayKeyTimer(Sender: TObject); 
begin 
    IsSearching := True; 
end; 

procedure TAgreementModuleForm.txtSearchAgreementCustomerExit(Sender: TObject); 
begin 
    IsSearching := False; 
end; 

procedure TAgreementModuleForm.txtSearchAgreementCustomerKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); 
var 
    vSearchExpression: string; 
begin 
    if IsSearching then 
    begin 
    vSearchExpression := Trim(txtSearchAgreementCustomer.Text); 
    IsSearching := False; 
    if vSearchExpression <> '' then 
     DoSearch(vSearchExpression); 
    end 
    else 
    tmrDelayKey.Enabled := True; 
end; 

tmrDelayKey是延時爲1000ms的TTimer。 IsSearching是一個布爾屬性。

這是用戶停止編寫搜索時無法使用的代碼。 這怎麼能改進?

+0

您可能會攔截Char(13)以根據需要進行搜索。您可以重置OnKeyup中的計時器(disbled/enabled),並處理OnTimer內的計時器搜索和禁用。 – bummi

+0

對於那個搜索編輯,我會寫一個組件['像這樣'](http://pastebin.com/45Z2d7pE)。它考慮到了任何變化,而不僅僅是當用戶在鍵盤上鍵入時(您應該考慮像通過彈出菜單粘貼文本等情況)。 – TLama

回答

2

我相信這個代碼應工作:

var SearchComplete: Boolean; 

procedure TForm1.DoSearch(Astring: String); 
begin 
    SearchComplete:= True; 
    txtSearchAgreementCustomer.Text := 'Searched: '+Astring; 
end; 

procedure TForm1.tmrDelayKeyTimer(Sender: TObject); 
begin 
    if not SearchComplete then 
    begin 
    DoSearch(txtSearchAgreementCustomer.Text); 
    end; 
end; 

procedure TForm1.txtSearchAgreementCustomerKeyUp(Sender: TObject; var Key: Word; 
    Shift: TShiftState); 
var C: Char; 
begin 
    C:= Char(Key); 
    if (C in ['a' .. 'z']) or (C in ['A' .. 'Z']) or (C in ['0'..'9']) then 
    SearchComplete := False; 
end; 


procedure TForm1.txtSearchAgreementCustomerExit(Sender: TObject); 
begin 
    tmrDelayKey.Enabled := False; 
end; 

procedure TForm1.txtSearchAgreementCustomerEnter(Sender: TObject); 
begin 
    tmrDelayKey.Enabled := True; 
    SearchComplete := True; 
end; 
+0

順便說一句。羅蘭,你有沒有想過當用戶輸入一些東西,然後通過鼠標通過上下文菜單從剪貼板粘貼文本的情況?這會導致在用戶停止寫入並超時後搜索到文本,但在編輯框中將從剪貼板粘貼文本。我真的更喜歡使用更改事件。 – TLama

5

最根本的問題是,你的搜索是同步的,並阻塞UI。添加延遲並沒有真正的幫助。用戶獲得反饋只需要更長的時間。

你需要做的是異步執行搜索。例如把它放在另一個線程中。搜索完成後,發信號通知主線程,以便顯示結果。如果用戶在搜索完成之前鍵入,則應使用更新後的搜索詞重新開始搜索。

此方法爲您提供響應式UI並儘快提供搜索結果。

注意:我假設,沒有理由讓你想避免反覆搜索。如果搜索成本很高,那麼絕對不希望在輸入時實現搜索。

+1

是的,你會得到一個負責任的用戶界面,但你會打擾搜索的來源(想想遠程請求)與絕對每一個改變你鍵入...用戶會很高興,但服務器將受到影響。只有我會實施這種延遲的情況。當然,使異步搜索是必須的.​​.. – TLama

+1

@TLama是的,我甚至沒有預料到搜索可能是昂貴的,應該配給。我沒有考慮到這一點,因爲它似乎與您輸入時的搜索不符。我添加了一些文字來澄清。 –

+0

搜索的執行使其無法從主線程移動。 –

相關問題