Специфический аналог ListView

Обсуждение проектов наших жителей.
Вы можете выставить проект на тест или найти помощников для его реализации.

Модератор: BV

MIT
Мега гуру
Мега гуру
Аватара пользователя
 
Сообщения: 2211
Зарегистрирован: 17.09.2006 (Вс) 22:46

Re: Специфический аналог ListView

Сообщение MIT » 11.03.2009 (Ср) 9:21

1Steps писал(а):При FormWindowState=Maximized это выглядит не красиво.
При FormWindowState=Maximized оно и не должно быть, т.к. "данный режим предполагался для использования в ограниченной ширине"

1Steps писал(а):Не додумался. И на мой взгляд никому не нужная фича.
Гы, не поверишь - получилась она совершенно случайно, я ее просто немного доделал. А так - есть не просит, особо не мешает, да и выключить ее можно.

Nord777 писал(а):Чтобы сильно тебя не мучать дам направление.
Система: WinXp Pro x64 Edition
Значин Integer там 8-байтовый?.. Тогда понятно откуда ошибка при работе с памятью
Изображение
You can change your face, but can`t change your mind. No matter what you do.
Создайте еще более понятный интерфейс и мир создаст еще более тупого юзера. (с) Баш

Nord777
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1144
Зарегистрирован: 22.02.2004 (Вс) 13:15
Откуда: Подольск

Re: Специфический аналог ListView

Сообщение Nord777 » 11.03.2009 (Ср) 11:06

Значин Integer там 8-байтовый?.. Тогда понятно откуда ошибка при работе с памятью

MsgBox(Hex(UInteger.MaxValue)) писал(а):FFFFFFFF


Добавлено:
Migrating 32-bit Managed Code to 64-bit
Microsoft Visual Studio 2008
Microsoft .NET Framework 3.5

MIT
Мега гуру
Мега гуру
Аватара пользователя
 
Сообщения: 2211
Зарегистрирован: 17.09.2006 (Вс) 22:46

Re: Специфический аналог ListView

Сообщение MIT » 13.03.2009 (Пт) 0:16

Nord777 писал(а):Добавлено:
Migrating 32-bit Managed Code to 64-bit
Спасибо за ссылку :) . Блин, вот не зайди я сюда, так бы и не узнал, что она тут меня дожидается :)

Осталась одна техническая проблемка: где бы взять XPx64 для испытаний? На моем любимом трекере только висты валяются...

З.Ы.: нашел у себя пару недоработок. Кстати, в выложенном примере - не тормоза, тормоза начинаются при 250 элементах :mrgreen:
Изображение
You can change your face, but can`t change your mind. No matter what you do.
Создайте еще более понятный интерфейс и мир создаст еще более тупого юзера. (с) Баш

MIT
Мега гуру
Мега гуру
Аватара пользователя
 
Сообщения: 2211
Зарегистрирован: 17.09.2006 (Вс) 22:46

Re: Специфический аналог ListView

Сообщение MIT » 23.04.2010 (Пт) 13:08

Вот и год прошел :)

Контрол действительно оказался никудышным: производительностью там даже и не пахло, да и количество костылей к окончанию разработки было таким, что архитектура стала похожа на запутанный комок ниток. Жаль, конечно, но блины часто комьями получаются.

От идеи написания этой штуки я еще не отказался, хотя она уже не настолько мне уже и нужна...
Наработка (написана с нуля) на данный момент выглядит довольно неплохо: спокойно оперирует десятками и сотнями тысяч элементов (даже парой-тройкой миллионов может), обладает кучей фич, в т.ч. гибкой архитектурой, основанной на интерфейсах, возможностью создания разных типов элементов с разным поведением и разными рендерами; позволяет как угодно перемещать элементы и, что самое главное, неплохим потанциалом к усовершенствованию.
И всё бы хорошо, но и тут с производительностью есть некоторые напряжные моменты.
Стандартный ListView содержит в себе элементы одинаковой высоты, в то время как у меня поддерживается любой размер для каждого отдельного элемента, поэтому вполне очевидна такая пробема: при изменении размера стандартного ListView просто перерисовываются элементы (ну и иногда изменяется их положение и количество), а вот у меня... У меня инициализируется индивидуальный перерасчет высоты каждого элемента, что бы тот смог сообщить контролу свою новую высоту при новой (переданной элементу) ширине.
Думаю не надо объяснять, что это довольно ресурсоёмкая операция: если для ста тысяч (и меньшего количества) элементов без текста перерасчет происходит достаточно быстро, то вот для уже десяти тысяч элементов с текстом (пара-тройка предложений, например) это уже отнимает по крайней мере секунду, а при малой ширине вообще несколько.

Хотел спросить: есть ли какая-нибудь теория, под которую можно подогнать расчет вероятности необходимости перерасчёта высоты? Ну например если отношение количества переносов в тексте к количеству печатных символов при известной средней ширине символа равно ..., то с ...%-ной вероятностью при изменении ширины области, в которую этот текст вписан на ...px надо будет пересчитать и высоту.

Я знаю что многого не знаю, например адаптировав алгоритм интерполяционного поиска под свои нужды получилось достаточно быстро находить нужный элемент в миллионной коллекции. Может и здесь что-нибудь придумано?
Изображение
You can change your face, but can`t change your mind. No matter what you do.
Создайте еще более понятный интерфейс и мир создаст еще более тупого юзера. (с) Баш

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: Специфический аналог ListView

Сообщение FireFenix » 23.04.2010 (Пт) 15:46

Т.к. юзер контрол юзается в .NET, то не проще его сделать в WPF? Там всё собирается стандартными средствами
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Re: Специфический аналог ListView

Сообщение Antonariy » 23.04.2010 (Пт) 15:57

Думаю не надо объяснять, что это довольно ресурсоёмкая операция: если для ста тысяч (и меньшего количества) элементов без текста перерасчет происходит достаточно быстро, то вот для уже десяти тысяч элементов с текстом (пара-тройка предложений, например) это уже отнимает по крайней мере секунду, а при малой ширине вообще несколько.
На экране постоянно находится меньше тысячи элементов, а чаще всего и меньше сотни. Зачем перерассчитывать высоту для остальных?
Лучший способ понять что-то самому — объяснить это другому.

MIT
Мега гуру
Мега гуру
Аватара пользователя
 
Сообщения: 2211
Зарегистрирован: 17.09.2006 (Вс) 22:46

Re: Специфический аналог ListView

Сообщение MIT » 23.04.2010 (Пт) 16:25

FireFenix
WPF я не знаю совсем, для меня это тёмный лес (хотя предполагаю, что научиться ему зная дотнет не сложно), посему — не вариант. Я сначала вообще на Си++ писать хотел, но в итоге остановился на шарпе.
Antonariy
Зачем? В идеале — для пересчета параметров скроллбара. Если это не делать сразу, то допросчитывать его между делом будет достаточно проблематично. Хотя можно считать только видимое, а остальное сваливать в фоновый поток...
Изображение
You can change your face, but can`t change your mind. No matter what you do.
Создайте еще более понятный интерфейс и мир создаст еще более тупого юзера. (с) Баш

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Специфический аналог ListView

Сообщение iGrok » 23.04.2010 (Пт) 16:40

MIT писал(а):Зачем? В идеале — для пересчета параметров скроллбара. Если это не делать сразу, то допросчитывать его между делом будет достаточно проблематично. Хотя можно считать только видимое, а остальное сваливать в фоновый поток...

Считай параметры скроллбара по номеру/кол-ву элементов, а не по высоте/общей высоте.
Может, не идеально, зато дёшево и практично.
label:
cli
jmp label

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Специфический аналог ListView

Сообщение Debugger » 23.04.2010 (Пт) 16:44

Или запоминай результаты расчетов.

MIT
Мега гуру
Мега гуру
Аватара пользователя
 
Сообщения: 2211
Зарегистрирован: 17.09.2006 (Вс) 22:46

Re: Специфический аналог ListView

Сообщение MIT » 23.04.2010 (Пт) 17:01

Результаты расчётов и так хранятся в памяти.
После вычисления высот всех элементов эти данные обрабатываются и создаётся многоуровневая карта, по которой можно почти моментально найти любой элемент, вычислить расстояние между элементами, получить идентификатор по расстоянию от начала или конца списка и т.п.. В процессе работы контрола эта таблица постоянно правится: добавляются, меняются и удаляются элементы, создаются и удаляются уравни градации, элементы перемещаются и в неё же записываются данные об изменеии высоты каждого отдельного элемента, как только он (элемент) попросил.

iGrok
Да, вариант не идеальный, учитывая вероятность того, что в какой-то определённый момент времени контрол может содержать в себе несколько длинющих элементов, каждый из которых единовременно не помещается на экране, но всё же имеющий право на существование.

Я, вот, подумал, что можно расчитвать площадь, занимаемую текстом, с точки зрения геометрии: т.е. если текст занимает прямоугольник 500х120рх, то вполне вероятно, что при изменении ширины с 500 на 400 его высота увеличиться со 120 на 500*120/400 и если дельта будет близка или больше определённого значения (высоты строчки), значит надо бы перерасчитать высоту всего текста. Вариант тоже не идеалньный, но его можно попробовать развить.
Изображение
You can change your face, but can`t change your mind. No matter what you do.
Создайте еще более понятный интерфейс и мир создаст еще более тупого юзера. (с) Баш

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Re: Специфический аналог ListView

Сообщение Antonariy » 23.04.2010 (Пт) 17:04

Debugger писал(а):Или запоминай результаты расчетов.
+1
Высоту каждого элемента нужно хранить в нем самом (надеюсь это объект?), при измененнии текста пересчитывать и предоставлять дельту(!) отдельным свойством. Общую запомненную высоту нужно пересчитывать при добавлении, удалении или изменении элемента, путем прибавления/вычитания к ней дельты (если она не ноль) или высоты элемента. После этого изменить значение скроллбара. Так же нужно запоминать индекс первого частично видимого элемента, чтобы не прочесывать всю коллекцию, сравнивая сумму высот элементов со значением скроллбара.
Лучший способ понять что-то самому — объяснить это другому.

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Re: Специфический аналог ListView

Сообщение Antonariy » 23.04.2010 (Пт) 17:18

Результаты расчётов и так хранятся в памяти.
Тогда почему так тормозит скролл?
Лучший способ понять что-то самому — объяснить это другому.

MIT
Мега гуру
Мега гуру
Аватара пользователя
 
Сообщения: 2211
Зарегистрирован: 17.09.2006 (Вс) 22:46

Re: Специфический аналог ListView

Сообщение MIT » 23.04.2010 (Пт) 17:39

Как так?
На то что выложено в этом топике ранее не стоит ровняться, я написал всё с нуля и пока еще никому не показывал.
Изображение
You can change your face, but can`t change your mind. No matter what you do.
Создайте еще более понятный интерфейс и мир создаст еще более тупого юзера. (с) Баш

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Re: Специфический аналог ListView

Сообщение Antonariy » 23.04.2010 (Пт) 17:59

И всё бы хорошо, но и тут с производительностью есть некоторые напряжные моменты.
Так напряженные моменты есть или нет? Если все таки есть, в какой момент они проявляются?
Лучший способ понять что-то самому — объяснить это другому.

MIT
Мега гуру
Мега гуру
Аватара пользователя
 
Сообщения: 2211
Зарегистрирован: 17.09.2006 (Вс) 22:46

Re: Специфический аналог ListView

Сообщение MIT » 23.04.2010 (Пт) 18:17

Да, они есть. Проявляются при ресайзе, когда количество элементов от десяти тысяч штук из-за причин, означенных выше.
Изображение
You can change your face, but can`t change your mind. No matter what you do.
Создайте еще более понятный интерфейс и мир создаст еще более тупого юзера. (с) Баш

MIT
Мега гуру
Мега гуру
Аватара пользователя
 
Сообщения: 2211
Зарегистрирован: 17.09.2006 (Вс) 22:46

Re: Специфический аналог ListView

Сообщение MIT » 25.04.2010 (Вс) 22:38

Я тут посидел подумал и в голове создались три возможных реализации перерасчёта данных способом, не напрягающих конечного юзера. Правда все они не идеальны..

Вариант 1: при изменении размера контрола перерасчёту подвергаются только видимые элементы (пусть их будет штук 10-20), данные скроллбара пересчитываются с новыми данными, информация о том что произошел ресайз и какие элементы пересчитаны запоминается с помощью какой-нибудь флаговой коллекции. При прокрутке списка перерасчитываются опять только видимые элементы, которые еще не пересчитывались, после чего ставятся флаги, что и их больше пересчиывать не надо.
Всё вроде хорошо, но есть один минус: возможна ситуация, когда скроллбар, данные которого не совсем достоверны, будет сильно неточно показывать положение пользователя в списке элементов. Например если у нас 20 элементов, первые десять из которых содержат немного текста и отображаются в текущий момент, а остальные — очень много текста и невидимы, то при ресайзе получится, что данные скроллбара изменятся незначительно, в то время как вторая десятка может изменить свою высоту, например, в два раза.

Вариант 2: при изменеии размера контрола перерасчёту подвергается опять только видимая часть элементов, данные скроллбара пересчитываются по этим временным данным, а расчёт остальных высот возлагается на фоновый поток. Поток работать будет от долей секунд до трёх целых (ну может чуть поболее для слабых машин), однако по его завершению у нас будет полная и точная информация. При этом можно визуально (в правом нижнем углу контрола) отображать сообщение, мол, идёт перерасчет данных.
Звучит тоже неплохо, но тут может быть проблема со скролингом во время перерасчёта, да и работа с потоками всегда связана с некоторыми трудностями при построении интерфейсов.

Вариант 3: объединить первый и второй, что бы перерасчет для видимих осуществлялся с приоритетом перед всем остальным, а это самое остальное высчитывалось в фоне.

Что думаете, какой из вариантов лучше? Может еще чего-нибудь тоже самое но другое в том же духе? Когда размышлял, склонялся ко второму, но пока писал пост — передумал в сторону третьего.
Изображение
You can change your face, but can`t change your mind. No matter what you do.
Создайте еще более понятный интерфейс и мир создаст еще более тупого юзера. (с) Баш

MIT
Мега гуру
Мега гуру
Аватара пользователя
 
Сообщения: 2211
Зарегистрирован: 17.09.2006 (Вс) 22:46

Re: Специфический аналог ListView

Сообщение MIT » 05.05.2010 (Ср) 23:04

Ладно, раз ни у кого нет желания думать за меня, значит просто смотрите :)

Прикладываю exe`шник со второй версией контрола. Делается он в свободное от всего время, так что не стоит удивляться большим временным периодам между этапами его создания.
В текущей версии реализовано многое из того что задумано, но всё-таки еще кое-каких вещей не хватает, в частности хочется отладить синхронизацию многопоточных вычислений, по возможности прикрутить возможность вставления в текст изображений, в т.ч. анимированных. Ну и еще выделение текста, использование html-образного синтаксиса для разметки внутри самих элементов плюс куча всяких неожиданных свистелок.
Основная фича этой версии — перетаскивание элементов.

Из известных глюков:
— возможно аварийное завершение фонового потока при ресайзе, который отвечает за не первоочередные вычисления, в связи с чем синхронность списка элементов и скроллбара не гарантируется. При возникновении такой ситуации следует нажать на кнопку Recalc Scroll, поможет.
— поведение контрола при выделении элементов может быть неочевидным (я про выделение нескольких элементов с использованием Ctrl и Shift`а), но хотел сделать лучше, а вот доделать как-то руки не доходят
(добавлено чуть попозже)
— если загрузить большой список элементов, выделить несколько последних, а потом загрузить меньший список, то возникнет исключение при попытке выделить еще чего-нибудь. Связано с тем, что коллекция выделенных элементов не очищается должным образом при удалении элементов

Пытался сделать оптимально с точки зрения производительности, но, думается мне, что есть куда улучшать :)

В качестве развлекаловки в данный билд я включил читалку файлов истории QIP Infium`а последних версий (проверял на версии 9030, но должно работать с историями достаточно большого диапазона версий), будет с чем поиграться.

Как всегда: любые глюки, замечания, идеи и предложения высказывайте здесь, буду рад их почитать.
Да, делал изначально под 64х битной системой, так что у Норд`а должно запустится :) . Рантайм — DotNET 2.0 (с копейками)
У вас нет доступа для просмотра вложений в этом сообщении.
Изображение
You can change your face, but can`t change your mind. No matter what you do.
Создайте еще более понятный интерфейс и мир создаст еще более тупого юзера. (с) Баш

Пред.

Вернуться в Наши проекты

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 21

    TopList