Есть ли способ повысить производительность моего простого текстового фильтра? - PullRequest
2 голосов
/ 05 мая 2010

Я пишу фильтр, который будет выбирать предметы. У меня есть список объектов. Объекты содержат номер, имя и некоторые другие не относящиеся к делу элементы. На данный момент список содержит 200 наименований. При вводе textbox я смотрю, соответствует ли строка части числа / имени объектов в списке. Если это так, добавьте их в listbox. Вот код для моего события с текстовым полем:

private void txtTelnumber_TextChanged(object sender, TextChangedEventArgs e)
    {
        lstOverview.Items.Clear();
        string data = "";
        foreach (ucTelListItem telList in _allUsers)
        {
            data = telList.User.H323 + telList.user.E164;
            if (data.Contains(txtTelnumber.Text))
                lstOverview.Items.Add(telList);
        }
    }

Иногда я вижу небольшую задержку при вводе символа, особенно когда я перехожу с 4 записей на 200 записей (поэтому, когда у меня был фильтр и 4 записи совпадают, и я возвращаюсь назад, и весь список появляется снова). Мой список представляет собой список пользовательских элементов управления, потому что я обнаружил, что загрузка пользовательских элементов управления из списка занимает меньше времени, чем каждый раз при инициализации нового пользовательского элемента управления.

Могу ли я что-то сделать с кодом или просто добавление usercontrol listbox, которое вызывает небольшую задержку (малая задержка = <1 сек)? </p>

Заранее спасибо.

Редактировать Я редактировал пост, это wpf. А размещение элементов в списке и установка источника элементов не решают проблему.

Ответы [ 6 ]

2 голосов
/ 05 мая 2010

Я бы посоветовал вам две техники для концерта:

  1. Перед очисткой и добавлением элемента в ListBox вызовите метод BeginUpdate() и вызовите его EndUpdate() после завершения добавления элементов. Эти методы специально созданы для того, чтобы избежать потери производительности при массовом добавлении элементов.
  2. Ввести таймер и запустить задачу фильтрации только по истечении определенного времени после последнего события KeyUp TextBox. Таким образом, вы увеличиваете вероятность того, что не оцените фильтр, который еще не важен для пользователя.
1 голос
/ 05 мая 2010

Я только что выяснил, что вызвало задержку при загрузке элементов в мой список. Я использую предопределенные темы (Wpf Themes) и, поскольку все мои списки скрыты, перерисовка занимает больше времени Так что это не имеет ничего общего с логикой программирования, просто стиль задерживает мой фильтр.

0 голосов
/ 24 октября 2011

Сначала вы должны получить все соответствующие элементы из своего списка с помощью лямбды, а затем попытаться использовать AddRange для добавления элементов в список.

0 голосов
/ 05 мая 2010

У вас есть только 200 предметов ???Вы не должны испытывать никакого отставания в производительности, чем в WPF.Просто заполните ваши данные в ObservableCollection и inturn привяжите их к списку.Теперь в вашем событии с измененным текстом вы можете применить ту же логику фильтра, но к ObservableCollection вместо списка.Представление списка должно отражать изменения немедленно.

Я работаю с миллионами записей без каких-либо задержек.

Вы никогда не захотите создавать задержки

Также обратите внимание на свойство VirtualMode для расширенных операций.

Обновление

И кажется, что вы выполняете эту операцию data = telList.User.H323 + telList.user.E164; в каждомтекстовое событие.Лучше заранее создать List<data> и реализовать только логику фильтра внутри цикла.

0 голосов
/ 05 мая 2010
private void txtTelnumber_TextChanged(object sender, TextChangedEventArgs e)
{ 
    lstOverview.DataSource=_allUsers.FindAll(delegate(ObjType telList)
    {
        return (telList.User.H323.Contains(txtTelnumber.Text) || telList.user.E164.Contains(txtTelnumber.Text) );
    });
}

попробуйте вышеуказанный код

0 голосов
/ 05 мая 2010

Оберните ваш код с помощью BeingUpdate / EndUpdate, чтобы остановить перерисовку при добавлении элементов.

private void txtTelnumber_TextChanged(object sender, TextChangedEventArgs e)
{
    lstOverview.BeginUpdate();
    lstOverview.Items.Clear();
    string data = "";
    foreach (ucTelListItem telList in _allUsers)
    {
        data = telList.User.H323 + telList.user.E164;
        if (data.Contains(txtTelnumber.Text))
            lstOverview.Items.Add(telList);
    }
    lstOverview.EndUpdate();
}
...