K>public override bool Equals(object obj)
K>{
K> var b2 = (Beacon)obj;
K> if (b2 == null) return false;
K> return ID != 0 && ID == b2.ID;
K>}
K>
.. K>К слову: может, что-то не так/медленно/неэффективно в самом Equals? Я его делал для записей СУБД, где очевидно, что если ID равны, то это один и тот же объект и нет смысла сравнивать поля.
Безотносительно тормозов в фильтрации грида (хз какого ), выделенное условие никогда не сработает (точнее сработает если obj == null), т.к. если obj не приводится к Beacon, то при касте будет исключение. Обычно проверяют через as: obj as Beacon.
вообще, обычно делают наоборот, т.е. сначала заворачивают данные в CollectionViewSource, а потом уже dataView используют как источник в других контролах:
по-идее, если так фильтровать, то Refresh уже не надо вызывать, фильтр автоматически применится. Refresh вызывают, когда надо пересоздать вью по какой-то причине.
Сам фильтр предельно простой: (obj) => obj.Property == true (к примеру). Ну то есть тормозить тут вообще нечему!
Что не нравится: КРАЙНЕ долгая фильтрация даже на 6 элементах!! Кликаю чекбокс, а список обновляется после секунды(!) фильтрации — почему так долго-то?? Подумаешь — Func сконструировал!
Вот не пойму, куда тут вообще копать. Может, грид можно как-то зафорсить "перефильтровать" чем-то помимо Refresh()? (если влиял именно он)
PS
Делал и без всяких хелперов — прям с формы делал GetDefaultView, назначал фильтр — та же медленная петрушка, т.е. дело точно не в Func/лямбдах.
Сам нашёл затык, но думаю, многим тоже будет полезно. А дело было... в перекрытом Equals!!
public override bool Equals(object obj)
{
var b2 = (Beacon)obj;
if (b2 == null) return false;
return ID != 0 && ID == b2.ID;
}
Вот эта зараза сразу просадила производительность до целой секунды на смешных 6 элементах — это как вообще?!
Но возникает другой вопрос: каким боком Equals к фильтрации?? Я же сам задаю критерий фильтрования!
К слову: может, что-то не так/медленно/неэффективно в самом Equals? Я его делал для записей СУБД, где очевидно, что если ID равны, то это один и тот же объект и нет смысла сравнивать поля.
Здравствуйте, Kolesiki, Вы писали:
K>Эврика!
K>Сам нашёл затык, но думаю, многим тоже будет полезно. А дело было... в перекрытом Equals!!
K>
K>public override bool Equals(object obj)
K>{
K> var b2 = (Beacon)obj;
K> if (b2 == null) return false;
K> return ID != 0 && ID == b2.ID;
K>}
K>
По гайдлайнам при перекрытии Equals должен быть переопределен оператор сравнения. Значит, проверка b2 == null пойдет в него.
K>Вот эта зараза сразу просадила производительность до целой секунды на смешных 6 элементах — это как вообще?! K>Но возникает другой вопрос: каким боком Equals к фильтрации?? Я же сам задаю критерий фильтрования!
K>К слову: может, что-то не так/медленно/неэффективно в самом Equals? Я его делал для записей СУБД, где очевидно, что если ID равны, то это один и тот же объект и нет смысла сравнивать поля.
Чисто версия. Если ID изменяемый, то он может ломать сравнение элементов. От этого может страдать производительность (и не только).
Здравствуйте, pilgrim_, Вы писали:
K>>public override bool Equals(object obj) K>>{ K>> var b2 = (Beacon)obj; K>> if (b2 == null) return false;
_>... выделенное условие никогда не сработает (точнее сработает если obj == null), т.к. если obj не приводится к Beacon, то при касте будет исключение. Обычно проверяют через as: obj as Beacon.
В моём случае за это можно не беспокоиться — сравнение применяется исключительно для Beacon объектов. Вопрос, за каким якодзуном WPF понадобился этот метод вообще?? Фильтрация грида — там мой кастомный фильтр, никаких Equals не вызывается.
Здравствуйте, notacat, Вы писали:
N>вообще, обычно делают наоборот, т.е. сначала заворачивают данные в CollectionViewSource, а потом уже dataView используют как источник в других контролах:
N>
N>по-идее, если так фильтровать, то Refresh уже не надо вызывать, фильтр автоматически применится. Refresh вызывают, когда надо пересоздать вью по какой-то причине.
Разве при присвоении к ItemsSource не создаётся автоматически DefaultView? (который я потом и получаю)
И фильтр не должен автоматически применяться — ведь грид не знает, от каких контролов зависит фильтр.
N>>по-идее, если так фильтровать, то Refresh уже не надо вызывать, фильтр автоматически применится. Refresh вызывают, когда надо пересоздать вью по какой-то причине.
K>Разве при присвоении к ItemsSource не создаётся автоматически DefaultView? (который я потом и получаю) K>И фильтр не должен автоматически применяться — ведь грид не знает, от каких контролов зависит фильтр.
проблема не в создании DefaultView, а в том, что если ваш грид и другие контролы были бы прибайндены к одному CollectionView, то условия фильтрации жили бы в этом CollectionView, и все контролы бы их просто использовали. Гриду вообще не надо знать, от каких контролов эти условия зависят. Он бы просто ловил изменения условий бесплатно для вас. А так вы руками все туда-сюда копируете, да еще рефрешите, конечно долго. Что на самом деле делает DataGrid с вашим источником данных, если он не CollectionView, слишком глубоко закопано. В принципе, гриды обычно в таких случаях ваш источник заворачивают во что-то, с чем удобно работать. Дополнительные накладные расходы, скорей всего еще один CollectionView
В смысле производительности гораздо дешевле создать нормальный источник, и забайндить его везде, чтобы грид с ним напрямую работал
N>>>по-идее, если так фильтровать, то Refresh уже не надо вызывать, фильтр автоматически применится. Refresh вызывают, когда надо пересоздать вью по какой-то причине.
K>>Разве при присвоении к ItemsSource не создаётся автоматически DefaultView? (который я потом и получаю) K>>И фильтр не должен автоматически применяться — ведь грид не знает, от каких контролов зависит фильтр.
N>проблема не в создании DefaultView, а в том, что если ваш грид и другие контролы были бы прибайндены к одному CollectionView....
Шта?? К коллекции прибайнден только грид.
N>, то условия фильтрации жили бы в этом CollectionView
Они и так там живут! Я же фильтр указал — он всегда и вызывается, ничего не пересоздаётся.
N>Гриду вообще не надо знать, от каких контролов эти условия зависят. Он бы просто ловил изменения условий бесплатно для вас
КАК? У меня текстовое поле, комбобокс, чекбоксы, радиобатоны... как он их будет отслеживать? Я делаю ровно наоборот — при изменении в фильтрующих контролах даю гриду команду "обновись".
N> А так вы руками все туда-сюда копируете, да еще рефрешите, конечно долго
Что именно копирую?? Рефрешу — да, но грид по-любому должен рефрешиться, как иначе он отфильтрует данные??
N> Что на самом деле делает DataGrid с вашим источником данных, если он не CollectionView, слишком глубоко закопано. В принципе, гриды обычно в таких случаях ваш источник заворачивают во что-то, с чем удобно работать.
Ну да. в DefaultView! Какой смысл мне его создавать, если грид и так его сделает??
N> Дополнительные накладные расходы, скорей всего еще один CollectionView
Нет никаких дополнительных — всё тот же вью, который грид создал под капотом.
N>В смысле производительности гораздо дешевле создать нормальный источник, и забайндить его везде, чтобы грид с ним напрямую работал
Список и есть "нормальный источник", мне не нужно лезть в потроха грида (или другого списочного элемента). Собственно, нам для этого и выставили ItemsSource, чтобы мы туда напрямую присваивали наши коллекции, не заботясь о деталях реализации.