![]() |
|
![]() ![]() ![]() |
|
mrgloom |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 829 Регистрация: 8.6.2011 Репутация: нет Всего: нет |
допустим у меня в программе есть CListBox и вектор который содержит экземпляры классов с именами для CListBox, так вот когда мне надо удалить из CListBox элемент, я прохожусь по вектору и удаляю нужный элемент по имени, потом очищаю листбокс и заполняю оставшимися значениями из вектора.
но этот подход не будет работать, если у нас одинаковые имена в листбоксе, возможно можно как то проставить ссылки? как это делают? Это сообщение отредактировал(а) mrgloom - 9.11.2012, 10:27 |
|||
|
||||
mrgloom |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 829 Регистрация: 8.6.2011 Репутация: нет Всего: нет |
всмысле вопрос сводится к тому как связать строчку выбранную в листбоксе с данными которые на листбокс выводятся, т.е. можно просто искать по строчке, но тогда нельзя использовать одинаковые названия. можно просто удалят ьпо номеру, но тогда надо следить, чтобы порядок на листбоксе и в векторе данных был один и тот же.
|
|||
|
||||
Albor |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 589 Регистрация: 28.2.2009 Репутация: 7 Всего: 9 |
У списков есть функция, с помощью которой можно связать элемент списка с данными (SetItemData()). Она принимает DWORD параметр, в который можно поместить либо число (индекс в массиве, например), либо указатель на данные. Но есть вещь покруче - это виртуальный список. Смысл в чём - данные находятся в контейнере, а контрол их отображает и вы фактически работаете только с контейнером. Контролу передаётся только количество отображаемых данных. Примера под рукой нет, но можно погуглить.
Это сообщение отредактировал(а) Albor - 9.11.2012, 15:29 |
|||
|
||||
Albor |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 589 Регистрация: 28.2.2009 Репутация: 7 Всего: 9 |
пример с использованием CListCtrl:
1. В свойствах CListCtrl ставим Owner Data в True; 2. Реагируем на уведомление LVN_GETDISPINFO - это список запрашивает данные для отображения;
В примере используется контейнер CArray содержащий некие объекты класса CKe, данные которого и должны отображаться в списке. 3. Сообщаем списку количество данных для отображения:
Всё. Теперь работаем с контейнером - добавляем, удаляем и не забываем вызывать SetItemCount(), чтобы список знал сколько ему отображать |
||||
|
|||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 87 Всего: 183 |
С одной стороны, все правильно, с другой - это решение из серии "зачем просто, когда можно сложно".
mrgloom говорил о ListBox, а не о ListCtrl, а это не одно и то же. Конечно, у ListCtrl возможностей намного больше, но и интерфейс сложнее. Засунуть строку в ListBox - одна строка кода и есть, и не нужно никакой предварительной подготовки. А виртуальный список тоже требует поддержки кодом, и это оправданно только когда это оправданно (например - много данных) Что касается использования DATA для каждого элемента списка, совет совершенно правильный. Либо в DATA записывается индекс в векторе строк (или более сложных структур). Но тогда придется обновлять DATA при удалении и вставке элементов в список. Либо можно хранить в DATA указатели на данные. Достаточно просто заменить вектор на список (std::list): в отличие от вектора список гарантирует валидность указателей при удалении и вставке элементов (кроме удаленных, конечно). Можно искать нужный элемент просто по указателю на данные на DATA. А можно вместо указателя на элемент данных хранить указатель на узел списка, из которого легко получается итератор. Но это не очень переносимо, и работает только в том случае, когда итератор списка простой (содержит только указатель на узел; в VC это означает, что отключена отладка итераторов). А можно, как написано в первом посте, просто перезаполнять список, что как-то неэкономно, но если список маленький, то почему бы и нет... -------------------- ... |
|||
|
||||
Albor |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 589 Регистрация: 28.2.2009 Репутация: 7 Всего: 9 |
так-то оно так, но лично мне не очень нравится вариант с "синхронизацией" 2х контейнеров. Я бы избавился от вектора и размещал данные в куче, сохраняя указатель на них в списке. |
|||
|
||||
mrgloom |
|
||||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 829 Регистрация: 8.6.2011 Репутация: нет Всего: нет |
ну вообщем я опять вернулся к этому вопросу, теперь мне нужен список с чекбоксами.
я заменил CListBox на CCheckListBox. допустим у меня список графиков класс графика состоит из name -имя points -точки is_show-показывать или нет список небольшой и можно впринципе и перезаполнять его. но я так и не понял как связать конкретную ячейку с конкретным графиком в списке. что такое m_pData- CArray от моего класса? что если я хочу использовать std vector? опять же еще вопрос я отлавливаю нажатие на чекбокс
во-первых похоже порядок отображаемый списке и порядок в спике в памяти разный, т.е. по номеру обращатся нельзя. во-вторых похоже что при нажатии на чекбокс, срабатывает только само событие нажатия и когда я пытаюсь опросить листбокс на предмет проставленных галочек в OnCheckChangeProfileList() то само состояние чекбокса еще не проставленно, не понятно как тут быть ,возможно надо оправшивать листбокс прямо перед отрисовкой(или например перед сохранением)?
Это сообщение отредактировал(а) mrgloom - 22.11.2012, 12:03 |
||||||
|
|||||||
Albor |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 589 Регистрация: 28.2.2009 Репутация: 7 Всего: 9 |
Немного подправлю
чтобы теперь получить индекс данных в векторе соответствующих выделенному в списке элементу, например, можно сделать так:
как уже писалось, использование в качестве DATA итераторов или указателей применительно к вектору не очень хорошо. Вектор может перераспределить память и все сохранённые итераторы (указатели) окажутся недействительными. Это сообщение отредактировал(а) Albor - 22.11.2012, 15:09 |
||||
|
|||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 87 Всего: 183 |
Немного добавлю
Список может быть сортированный или нет. Это выставляется в свойствах. По-умолчанию, кажется, студия ставит сортировку. Удобнее всего с несортированным списком - вообще мудрить не надо, ибо порядок в списке совпадает с порядком добавления - если ты, конечно, в конец добавляешь: номер в списке == индекс в векторе. Удаляй, добавляй - главное, синхроннно. А вот если нужна сортировка, тогда пригодится data: записывай туда индекс соответствующего элемента, как показал Albor: AddString возвращает позицию, в которую реально попал новый элемент. Но еще раз, она не совпадает с индексом в векторе (в приведенном коде) только для сортированного списка. -------------------- ... |
|||
|
||||
![]() ![]() ![]() |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |