2011-12-27 60 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(); 

希望这会有所帮助。