2013-04-29 13 views
1

我正在製作一個使用C#和Windows窗體的字典。在我的字典中,我有一個textBox,用戶可以在其中搜索單詞以獲得含義。我還在comboBox中有一些選項,用戶可以選擇一種語言來查看該語言的含義。因爲我正在爲不同的語言製作字典。使用textBox_TextChanged事件和if語句一起寫入文本框的速度越來越慢。

我的代碼如下所示:

private void textBox1_TextChanged(object sender, EventArgs e) 
{ 
    string word = textBox1.Text; 

    SqlCeConnection con = new SqlCeConnection(@"Data Source=" + Directory.GetCurrentDirectory() + @"\Database\condrokothadb.sdf;Password=000;"); 

    //in combobox there are 2 option(language) 
    //if select one language(option) from combobox 
    if(mood=="bangla") 
    { 
     SqlCeDataAdapter b = new SqlCeDataAdapter("SELECT english,bangla FROM dic WHERE (bangla like '" + word + "%')", con); 
     DataTable tt = new DataTable(); 
     b.Fill(tt); 
     dataGridView1.DataSource = tt; 
    } 
    else //by default english language is selected 
    { 
     using (con) 
     { 
      con.Open();    
      using (SqlCeDataAdapter b = new SqlCeDataAdapter("SELECT english,bangla FROM dic WHERE (english like '" + word + "%')", con)) 
      { 
       DataTable tt = new DataTable(); 
       b.Fill(tt); 
       dataGridView1.DataSource = tt; 
      } 
     } 
    } 
} 

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) 
{ 
    if (((ComboBox)sender).SelectedItem.ToString() == "Bangla") 
    { 
     mood = "bangla"; 
    } 
    else if (((ComboBox)sender).SelectedItem.ToString() == "English") 
    { 
     mood = "english"; 
    } 
} 

我的問題是,當用戶想要寫的東西到它現在這麼慢得多寫文本框。我如何克服這一點?

回答

1

而不是從每個文本中的服務器獲取數據更改,您可以立即獲取網格中的所有數據,然後用dataview過濾它們。

// to get data in grid 
CustomList<wordlistDAO> WordList = null; 
WordList = WordListBLL.GetAllWord(); 
GridWord.DataSource = WordList ; 

// create word datatable for filtering 
DataTable dtWord = null; 
dtWord = new DataTable(); 
foreach (DataGridViewColumn colu in GridWord.Columns) 
         dtWord .Columns.Add(new DataColumn(colu.HeaderText)); 
foreach (DataGridViewRow row in GridWord.Rows) 
{ 
    DataRow dr = dtWord.NewRow(); 
    foreach (DataGridViewCell cell in row.Cells) 
     dr[row.Cells.IndexOf(cell)] = cell.Value; 
     dtWord .Rows.Add(dr); 
} 

//create data view 
DataView wordlistview = new DataView(); 
wordlistview = new DataView(dtWord); 

// filter dataview and show in grid 

if (cboLanguage.Text == "Bangla") 
{ 
    wordlistview.RowFilter = "bangla LIKE '" + txtSearchValue.Text.Trim().ToUpper() + "%'"; 
} 
else 
{ 
wordlistview.RowFilter = "english LIKE '" + txtSearchValue.Text.Trim().ToUpper() + "%'"; 
} 
GridWord.DataSource = wordlistview; 
+0

我無法理解如何將所有數據保存到數據表中並進行數據視圖。請您給我詳細信息? – DarkenShooter 2013-04-30 06:00:57

+0

我假設你在你的數據視圖中有英文和孟加拉語2列。在這種情況下,你可以根據從combobox(cboLanguage)中選擇的語言過濾你的數據視圖。我編輯了我的答案。請檢查最後一行代碼。希望它能爲你工作。 – 2013-04-30 06:17:59

+0

你不需要datalist。似乎你在你的數據表(tt)中獲得了你的數據。現在你可以從'create data view'步驟進行操作。 – 2013-04-30 07:39:00

1

主要問題是,每次按下文本框中的某個鍵時,都會創建數據庫連接並查詢數據庫。這是非常低效的!此外,由於Bangla代碼不會處理連接,因此您可能會保留很多不需要的對象,因此隨着時間的推移,您可能會發現性能正在下降。

一個基本的建議是使用一個連接,而不是爲每個按鍵打開新的連接。這會稍微減少查詢所花費的時間。實際上,我懷疑你想要一次加載數據的全部內容,並在內存中運行你的查詢。這會給你更好的速度。

在後臺線程上運行查詢將有助於維護您的UI的響應能力,但可能最終會有大量查詢立即嘗試追趕用戶的輸入。

一個更好的解決方案是考慮運行「空閒計時器」,並且只在用戶停止短時間輸入時纔開始查詢。我建議仍然使用後臺線程。您不會爲每個按鍵查詢數據庫,也不會影響UI的響應。

+0

「我懷疑你想要加載數據的全部內容,並在內存中運行你的查詢,這會給你更好的速度」我怎麼做? @丹Puzey – DarkenShooter 2013-04-29 09:49:35

1

在數據庫中進行任何按鍵搜索都是不好的做法。正如你已經經歷的那樣,它會讓用戶界面非常緩慢。更好的選擇是在後臺線程中進行搜索,而不是每次擊鍵。在進行搜索之前,您可以等待一段時間(例如0.5秒)。如果用戶同時按下另一個鍵,則再次將等待時間再延長0.5秒。

+0

我該怎麼做? – DarkenShooter 2013-04-29 09:51:08

+0

@DarkenShooter對不起,我現在很忙。有空閒時我會實施一個工作解決方案。 – 2013-04-29 12:35:53

1

延遲可能是由於數據庫中的大量數據造成的,並且您正在爲每個文本更改的事件調用數據庫。 我會建議的是將所有數據都放入DataView中,並保持過濾和綁定網格與來自視圖的結果。這樣可以最大限度地減少數據庫被調用的次數。

+0

如何從dataview中搜索數據以及如何將結果數據綁定到dataGridView? @Prabhu – DarkenShooter 2013-04-29 10:25:18

2

這是一個有趣的問題,這裏是我將如何解決它。

我添加了一個計時器,當您在文本框中輸入第一個字符時開始計數,併爲添加計時器的每個字符重置。應用程序不會執行通過數據庫進行搜索的部分,直到計時器達到設定的滴答數。

請確保您在表單中添加了timerbackgroundWorker。創建通過屬性窗口中的事件,並添加以下代碼:

int timerTicks; 
int waitUntill = 10; //10 = 1 second. Change this to decide how long the application will wait. 

string mood; 
string word; 
string langConnection; 

DataTable tt; 
SqlCeConnection con; 
SqlCeDataAdapter b; 

private void textBox1_TextChanged(object sender, EventArgs e) 
{ 
    if (!timer1.Enabled) 
     timer1.Start(); 
    //Reset the timer when a character is entered in textBox1. 
    timerTicks = 0; 
} 

private void timer1_Tick(object sender, EventArgs e) 
{ 
    timerTicks++; 

    if (timerTicks > waitUntill && !backgroundWorker1.IsBusy && comboBox1.SelectedItem != null) 
    { 
     //Stop the timer and begin the search in a background thread. 
     timer1.Stop(); 
     word = textBox1.Text; 
     mood = comboBox1.SelectedItem.ToString(); 
     backgroundWorker1.RunWorkerAsync(); 
    } 
} 

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    tt = new DataTable(); 
    con = new SqlCeConnection(@"Data Source=" + Directory.GetCurrentDirectory() + @"\Database\condrokothadb.sdf;Password=000;"); 

    langConnection = String.Format("SELECT english,bangla FROM dic WHERE ({0} like '{1}%')", mood, word); 

    using (con) 
    { 
     con.Open(); 
     b = new SqlCeDataAdapter(langConnection, con); 
     b.Fill(tt); 
    } 
} 

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    dataGridView1.DataSource = tt; 
} 

請注意,您不需要comboBox1_SelectedIndexChanged事件這個工作。

編輯:

爲了使實際的搜索運行速度更快,你必須打開在啓動時連接並保持整個執行的全部打開,像其他答案建議爲好。儘管如此,你應該可以自己弄清楚。

+0

它有點快,但不是我所期望的...請給出另一種方式,將會更快。 – DarkenShooter 2013-04-29 13:35:04

+0

@DarkenShooter試試我更新的答案! – 2013-04-29 13:51:36

+0

dataGridView1.DataSource = tt;在這一行'tt'不能被訪問。 – DarkenShooter 2013-04-29 15:05:42