Windows Phone 7 - Проблемы с производительностью при использовании функции «Фильтр при написании» - PullRequest
1 голос
/ 11 сентября 2011

У меня есть некоторые проблемы с производительностью при реализации функции, когда список фильтруется в реальном времени, пока пользователь вводит строку фильтра в текстовое поле. Функция, которую я пытаюсь создать, похожа на поиск по истории вызовов в WP7.

Я создал простой проект для проверки этого и скопировал важные биты ниже. В основном у меня есть TextBox, где пользователь должен написать строку, которая будет использоваться для фильтрации данных, связанных со списком. Эта фильтрация должна выполняться в режиме реального времени, а не после нажатия какой-либо кнопки фильтра и т. Д.

ListBox привязан к CollectionViewSource, который использует ObservableCollection в качестве источника. Когда что-то вводится в текстовое поле, это значение мгновенно привязывается к свойству в модели представления. Установщик свойства View Model запускает фильтрацию CollectionViewSource, которая обновляет содержимое ListBox.

В реальном проекте, который я делаю, ListBox может содержать около сотни элементов.

Вот соответствующий XAML:

        <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>

Код для запуска мгновенной привязки к свойству ViewModel:

    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-класс, привязанный к списку данных:

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; }
}

Вопрос:

Все работает хорошо, но между записью в TextBox и обновлением ListBox существует огромная задержка.

Я просто делаю это неправильно? Если так, то как мне изменить свой подход? Я думаю, что это довольно распространенное требование, поэтому, вероятно, есть хорошее решение для него.

1 Ответ

1 голос
/ 12 сентября 2011

Вместо использования собственного фильтра, вы можете использовать AutoCompleteBox из набора инструментов ?

В качестве альтернативы, вы могли бы классифицировать данные и сделать их доступными для поиска через LongListSelector?

В конечном итоге, если у вас плохой код, вы должны использовать Profiler, чтобы увидеть, где на самом деле находится узкое место. http://msdn.microsoft.com/en-us/library/hh202934(v=vs.92).aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...