2011-09-11 8 views
1

ユーザーがフィルタ文字列をテキストボックスに入力しているときに、リストボックスがリアルタイムでフィルタ処理される、機能の実装にパフォーマンス上の問題があります。私が作成しようとしている機能は、WP7の通話履歴検索に似ています。Windows Phone 7 - "フィルタ書き込み時のパフォーマンス"問題 - 機能

これをテストし、以下の重要な部分をコピーして貼り付けた簡単なプロジェクトを作成しました。基本的に私は、リストボックスにバインドされたデータをフィルタリングするために使用される文字列を書くことになっているTextBoxを持っています。このフィルタリングは、フィルタボタンなどの任意の種類をタップした後ではなく、リアルタイムで行われる必要があります。ListBoxはObservableCollectionをソースとして使用するCollectionViewSourceにバインドされています。テキストボックスに何かが入力されると、その値はすぐにビューモデルのプロパティにバインドされます。 Viewモデルプロパティのセッターは、ListBoxの内容を更新するCollectionViewSourceのフィルタリングを起動します。

私がやっている実際のプロジェクトでは、リストボックスは100程度のアイテムを含むことができます。背後のViewModel-プロパティに結合する瞬間をトリガするために

 <TextBox TextChanged="TextBox_TextChanged" Text="{Binding FilterString, Mode=TwoWay, UpdateSourceTrigger=Explicit}"></TextBox> 

     <ListBox ItemsSource="{Binding ItemsListCVS.View, Mode=TwoWay}"> 
      <ListBox.ItemTemplate> 
       <DataTemplate> 
        <TextBlock Text="{Binding Prop1, Mode=TwoWay}"></TextBlock> 
       </DataTemplate> 
      </ListBox.ItemTemplate> 
     </ListBox> 

コード:

private void TextBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e) 
    { 
     var textBox = sender as TextBox; 
     // Update the binding source 
     BindingExpression bindingExpr = textBox.GetBindingExpression(TextBox.TextProperty); 
     bindingExpr.UpdateSource(); 
    } 

のViewModel:にデータバインドされ

private ObservableCollection<AnItem> _itemsList = new ObservableCollection<AnItem>(); 
    private CollectionViewSource _itemsListCvs = new CollectionViewSource(); 


    public ObservableCollection<AnItem> ItemsList 
    { 
     get 
     { 
      return _itemsList; 
     } 

     set 
     {   
      _itemsList = value; 

      // Update bindings, no broadcast 
      RaisePropertyChanged(ItemsListPropertyName); 
     } 
    } 

    public string FilterString 
    { 
     get 
     { 
      return _filterString; 
     } 

     set 
     { 
      if (_filterString == value) 
      { 
       return; 
      } 

      _filterString = value; 

      // Update bindings, no broadcast 
      RaisePropertyChanged(FilterStringPropertyName); 

      this.Filter(); 
     } 
    } 
    public CollectionViewSource ItemsListCVS 
    { 
     get 
     { 
      return _itemsListCvs; 
     } 

     set 
     { 
      if (_itemsListCvs == value) 
      { 
       return; 
      } 

      _itemsListCvs = value; 

      // Update bindings, no broadcast 
      RaisePropertyChanged(ItemListPropertyName); 
     } 
    } 

    public MainViewModel() 
    { 
     var items = Builder<AnItem>.CreateListOfSize(100).Build(); 
     this.ItemsList = new ObservableCollection<AnItem>(items); 
     this.ItemsListCVS.Source = this.ItemsList; 
    } 

    private void Filter() 
    { 
     this.ItemsListCVS.View.Filter = r => 
     { 
      if (r == null) return true; 
      return ((AnItem)r).Prop1.ToString().ToLowerInvariant().Contains(FilterString); 
     };    
    } 

AnItemクラスここで

は、関連するXAMLですリスト:

public class AnItem 
{ 
    public string Prop1 { get; set; } 
    public string Prop2 { get; set; } 
    public string Prop3 { get; set; } 
    public string Prop4 { get; set; } 
    public string Prop5 { get; set; } 
} 

質問:

すべてが大丈夫働いているが、リストボックスのテキストボックスと更新への書き込みの間に恐ろしい遅れがあります。

私は単に間違っていますか?もしそうなら、どうすれば私のアプローチを変えるべきですか?私はこれがかなり共通の要件だと思うので、おそらくそれのための素晴らしい解決策があります。

答えて

1

独自のフィルタをローリングするのではなく、toolkitのオートコンプリートボックスを使用できますか?

代わりに、データを分類し、LongListSelectorで検索可能にすることができますか?

最終的にパフォーマンスの低いコードがある場合は、プロファイラを使用して実際のボトルネックがどこにあるかを確認する必要があります。 http://msdn.microsoft.com/en-us/library/hh202934(v=vs.92).aspx

+0

遅くならないほどいいですか?私は他のプロジェクトに従事していたので、私はWP7の任務を怠った。とにかく、私はそれがフィルタリングされた出力が意志で指示されることがわかったときに私はAutoCompleteBoxを使用して終了しました。ありがとう! – juarola

関連する問題