| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > WPF и Silverlight > Почему Canvas так долго думает |
| Автор: ivanfain 19.3.2012, 16:53 |
| Я вот думал, WPF несказанно крут, DirectX и всякой такое. Но реально я хочу разместить несколько тысяч ячеек и это занимает несколько секунд. Ячейка - это просто UserControl, на Canvas. UserControl не сложный, текстовое поле TextBlock и Border. Результат должен быть на подобии листа Excel. Но вот всё это не реально долго. Как оптимизировать? Реально ли сделать отрисовку нескольких тысяч ячеек меньш секунды. Excel ведь это умеет, да и не на WPF он написан. Спасибо. |
| Автор: Stas123 19.3.2012, 19:37 |
| Подумайте, может стоит использовать паттерн "Приспособленец"(Flyweight). |
| Автор: ivanfain 19.3.2012, 19:47 |
| А как его использовать? Каждая ячейка имеет уникальные координаты, поэтому трудно обойтись одним объектом. |
| Автор: exBlender 19.3.2012, 22:01 | ||
А для чего каждой ячейке иметь уникальные координаты и быть посаженной на Canvas, eсли все это должно быть похожим на таблицу? Почему не использовать DataGrid или, хотя бы, просто Grid? |
| Автор: ivanfain 19.3.2012, 23:01 |
Потому что это будет не стандартная таблице. Не знаю как насчёт DataGrid но через обычный Grid это сделать можно. Вы утверждаете что скорость отрисовки будет больше? |
| Автор: SergeyLoginov 20.3.2012, 16:52 |
| WPF очень медленно отрисовывает большое количество визуальных элементов. Но в Вашем случае можно использовать виртуализацию данных. В частности, существует виртуализированный http://blogs.msdn.com/b/jgoldb/archive/2008/03/08/performant-virtualized-wpf-canvas.aspx, в котором рендерятся только видимые на экране элементы. В DataGrid, кстати, тоже реализована виртуализация. |
| Автор: erm0l0v 21.3.2012, 08:51 |
| Используйте DataGrid. Canvas не для этого предназначен. И как вам вообще пришла в голову мысль использовать Canvas? Элементы ведь можно по координатам размещать и в Grid. В общем попробуйте реализовать задачу с использованием DataGrid. Это будет самый оптимальный способ. В крайнем случае через Grid. |
| Автор: erm0l0v 22.3.2012, 09:05 | ||
Я такого не делал но уверен почти на 100 процентов что это возможно сделать по средствам стилей. В WPF стилями можно изменить вообще все. По поводу что делать поставьте профайлер памяти и вы сможете увидеть какие классы занимают больше всего места. На первый взгляд копать нужно в сторону большого количества UserControl. Кроме того возможно неправильно настроен ScrollViewer. Возможно в приложении ошибка которую вы не ведите из-за пустого catch. И все таки ради теста попробуйте отобразить данные в DataGrid если будет работать так же долго то проблема не в визуальном отображении. У меня таблица из 100к строк и примерно 15 столбцов строится очень быстро, меньше секунды и учетом того что данные еще тянутся из базы и некоторые поля таблицы вычисляются. |
| Автор: ivanfain 22.3.2012, 09:48 | ||||||
Дело не в памяти, а в процессорном времени
Там и теряется перформанс.
Если вы покажете как переопределить стиль DataGrid чтобы он выглядел так, как это показано на изображении. С возможность в добавлять и убирать головы(как сверху так и слева), а следоватьльно и менять количество ячеек, буду вам очень признателен. Если же это просто разговоры - тогда плохо. http://xmages.net/i/3430841 |
| Автор: erm0l0v 23.3.2012, 09:34 |
| Теперь понятно почему вы решили использовать Canvas)) Только может быть Canvas работал бы быстрее если вы не добавляли контролы а рисовали таблицу примитивами, но это конечно жестоко. По поводу DataGrid для отображения заголовков в левой части можно использовать группировки, но правда меня разочаровала скорость работы группировки в DataGrid в WPF особенно по сравнению с Silverlight. По поводу группировки заголовков сверху и объединенных ячеек справа я пока ничего не могу придумать((( если что нибудь придет на ум отпишусь... Вроде есть компоненты для отображения таблиц Excel в WPF (я нашел только платные) и есть компоненты в Windows Forms вы принципе можете использовать компоненты из WF в WPF но опять же скорость работы WinFormsHost меня разочаровала. |
| Автор: ivanfain 23.3.2012, 13:49 | ||
Теперь перешёл на Grid, потому как Canvas не адекватно отрисовывается. Для него почему-то не работает нормально SxrolViwer. Портировать на Grid было делом 15 минут. Меня смущает то, что я добавляю элементы в коллекцию в цикле
Может как-то нужно остановить отрисовку прежде чем начать добавлять? Но боюсь WPF это и так делает. Скорее всего он останавливает отрисовку пока не будут добавлены все элементы. |
| Автор: erm0l0v 23.3.2012, 16:06 | ||
| Сейчас для теста вывел таблицу 10000 на 5 ждал 10 секунд. По идеи
должна остановить отрисовку, но в моем примере это не помогло (или помогло но незначительно). |
| Автор: exBlender 23.3.2012, 22:20 |
| А зачем там вообще UserControl-ы? С такой графикой можно просто назначать Background для TextBlock-ов. |
| Автор: ivanfain 26.3.2012, 20:40 |
| Там логика в UserControl-ах содержится. Её конечно можно вынести отдельно, но будет ли профит? Хотя бы 10% производительности получу? Сомневаюсь. |