2011-12-27 48 views
3

我有一個WPF應用程序,通過工具包(VS 2008)自動完成框。我有大約2000條記錄的潛在人口,我試圖通過組合填充事件過程來提高性能。我得到的結果不一致。該過濾器似乎沒問題,但我可以運行應用程序一次,結果X將在那裏,但結果Y不會。再次運行它可以使結果Y在那裏而不是X,隨後的時間X和Y都會在那裏,等等等等。這是我第一次使用自動完成框,所以我相信它肯定是我的代碼中的東西,我忘了。如果在Itemsource綁定之前檢查我的結果集,那麼所需的結果就在那裏,但它們對用戶不可見 - 下拉式自動完成後不顯示。也許我需要一個事件重寫?自動完成框 - 來自人口的值不一致

的XAML

<input:AutoCompleteBox       
Name="autGlobal" 
FilterMode="Contains" 
Style="{DynamicResource MiniSearchAutoBoxWPF}" 
IsTextCompletionEnabled="false" 
Margin="5, 0, 5, 0" 
HorizontalAlignment="Center" 
KeyUp="autGlobal_KeyUp" 
Text="Search Term" 
GotFocus="autGlobal_GotFocus" 
ValueMemberPath="Item" 
Populating="AutoCompleteBox_Populating" 
> 

方法

private void AutoCompleteBox_Populating(object sender, PopulatingEventArgs e) 
      { 
      e.Cancel = true; 
      var b = new BackgroundWorker(); 
      currSearch = autGlobal.Text; 
      b.DoWork += b_DoWork; 
      b.RunWorkerCompleted += b_RunWorkerCompleted; 
      b.RunWorkerAsync(autGlobal.Text); 
     } 

private void b_DoWork(object sender, DoWorkEventArgs e) 
     { 
      Results.Clear(); 
      int counter = 0; 
      string search = e.Argument.ToString(); 
      search = search.ToUpper(); 
      foreach (GlobalSearchList person in myGlobalList) 
      { 
       if (person.Item.ToUpper().Contains(search)) 
       { 
        Results.Add(person); 
        counter++; 

        if (counter >= MAX_NUM_OF_RESULTS) 
        {       
         break; 
        } 
       } 
      } 
     } 

private void b_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 

      if (this.Dispatcher.Thread == System.Threading.Thread.CurrentThread) 
      { 
       //Set the source 
       if (currSearch == autGlobal.Text) 
       { 
        autGlobal.ItemsSource = Results; 
        autGlobal.PopulateComplete(); 
       } 
      } 
      else 
      { 
       this.Dispatcher.Invoke(new Action(() => 
       { 
        //Set the source 
        if (currSearch == autGlobal.Text) 
        { 
         autGlobal.ItemsSource = Results; 
         autGlobal.PopulateComplete(); 
        } 

       })); 
      }    
     } 
+0

似乎這種情況正在做一些事情......「counter> = MAX_NUM_OF_RESULTS」..​​我認爲這是防止少數記錄.. – Bathineni 2012-01-05 17:39:59

回答

3

我不知道爲什麼你需要擺在首位的性能提升,你要計算出應在自動完成框,另一個線程的元素,然後將它們分配給ItemsSource控制權的財產。類似的東西是什麼AutoCompleteBox應該做的。

我嘗試將控件綁定到10000個字符串的列表,它的工作原理非常完美,所以您的問題可能是您要放入集合中的對象的大小。一種解決方案可以只使用字符串表示,然後當你需要選定的對象時,你可以根據它的表示來找到它,假設它是唯一的(如果不是,你可以放置某種ID)。

這種方法的主要問題之一是線程sincronization,我現在將解釋爲什麼你會得到extrange行爲,即使過濾器很好,結果中的項目是不正確的。

該過濾器似乎沒問題,但我可以運行該應用程序一次,結果X將 在那裏,但結果Y不會。再次運行它可以使結果Y是 那裏,而不是X,隨後的時間X和Y會在那裏等,等

假設你寫的「AB」的自動完成框,這將啓動執行此搜索的新的BackGroundWorker。如果你等待足夠長的時間,一切都會好的。但是,如果在第一個工作人員完成之前更改搜索查詢,現在所有結果都會混合在一起。舉例如下幾行代碼:

// the user searchs for "ab" 
[Thread 1] Results.Clear(); 
[Thread 1] Results.Add(Item[1]); 
[Thread 1] Results.Add(Item[2]); 
... 
// the user changes the search term (to "abc" for example) 
[Thread 2] Results.Clear(); 
[Thread 2] Results.Add(Item[3]); 
// but what would happen if the first BackGroundWorker hasn't finished yet, 
// this means that the first thread is still running 
[Thread 1] Results.Add(Item[5]); // this items doesn't match the second search 
[Thread 1] Results.Add(Item[6]); // criteria, but are added to the collection 
[Thread 2] Results.Add(Item[7]); 
// then you'll have two treads adding items to the Result collection 
[Thread 1] Results.Add(Item[2]); 
... 
[Dispatcher Thread] autGlobal.ItemsSource = Results; 
[Dispatcher Thread] autGlobal.PopulateComplete(); 

希望這會有所幫助。