Spam78 Ответов: 2

Cchecklistbox сортирует автоматически


Я пытаюсь динамически создать CCheckListBox в C++ MFC, но по какой-то причине он автоматически сортирует записи в алфавитном порядке, что влияет на последующий код. Код, используемый для его создания, таков::

m_List = new(CCheckListBox);
m_List->Create(LBS_HASSTRINGS | LBS_OWNERDRAWFIXED | WS_CHILD | BS_CHECKBOX | WS_VISIBLE , CRect(20, 20, 180, 180), this, 1248);


и следующая функция добавляет строки в checklistbox из CEdit.

void CCheckListBoxDlg::addEntry()
{
	CString strTemp;
	m_Entry->GetWindowTextW(strTemp);
	m_List->AddString(strTemp);
}


Обратите внимание, что это не имеет свойств LBS_SORT или LBS_STANDARD, но все равно сортируется. Тот же код использует CListBox (от которого наследуется CCheckListBox) без этой проблемы.

Что я уже пробовал:

Я воссоздал это из пустого приложения MFC, чтобы подтвердить, что ничто другое в коде не отвечает за это, и что CCheckListBox сортирует в точке входа.

РЕДАКТИРОВАТЬ: Ссылка на GitHub. Содержит форму с CCheckListBox, CEdit и CButton, которая добавляет содержимое CEdit в CCheckListBox.

Я также пытался использовать ModifyStyle/Ex для удаления свойства LBS_SORT, которого у него не должно быть, но это не имеет никакого эффекта.

Shao Voon Wong

Можете ли вы загрузить свое пустое приложение MFC (которое воспроизводит проблему) на GitHub, и мы посмотрим.

Spam78

https://github.com/SPG78/CCheckBoxList/tree/main/CheckListBox

Rick York

Вопрос для вас : правильно ли CCheckListBox визуализирует себя для вас? В течение многих лет он никогда не будет для меня, и это было достаточно раздражающе, что я полностью отказался от его использования некоторое время назад. Я пишу пользовательский, изменяемый размер диалог с производным CListCtrl, который включает в себя флажки, и это работает гораздо лучше для меня.

Spam78

Кажется, это прекрасно работает для меня. Я не играл со шрифтами или чем-то подобным, но стиль по умолчанию отображается правильно.

2 Ответов

Рейтинг:
8

Shao Voon Wong

После удаления BS_CHECKBOX от Create()- сейчас он не сортируется.

m_List->Create(LBS_HASSTRINGS | LBS_OWNERDRAWFIXED | WS_CHILD | WS_VISIBLE , CRect(20, 20, 180, 180), this, 1248);


Spam78

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

Рейтинг:
2

Rick York

Часто сортировка списка является предпочтительным поведением пользователя, и с этим достаточно легко справиться. Когда вы звоните AddString он возвращает индекс. Тогда вы можете позвонить SetItemData и передайте ему указатель или значение, чтобы связать с этой записью в списке. С помощью этой ассоциации, когда пользователь нажимает кнопку ОК или дважды щелкает или какое-либо другое событие, которое вы отслеживаете, чтобы выбрать элемент, происходит, вы можете позвонить GetCurSel чтобы получить текущий выбор, а затем, с этим индексом, вы можете позвонить GetItemData чтобы получить значение или указатель, которые вы ранее связали с этим элементом списка. Использование этого метода позволяет сортировать список или нет, и вашему коду не нужно беспокоиться, потому что вы связали свои данные с элементами в списке.

Я делаю это так часто, что сделал маленькие обертки, чтобы добавить строку и значение данных с одним вызовом. Он соединяет два вызова, упомянутых выше, AddString и SetItemData вместе как один вызов - AddStringData. Я также сделал соответствующую функцию для получения выбранной строки и ее данных : GetSelectedStringData, которая обертывает GetCurSel, GetItemData, и GetString (Я думаю, что это так) вместе.


Rick York

Кстати - вы можете заметить, что я упоминал выше, что я перестал использовать CCheckListBox некоторое время назад, и я это сделал. Как уже упоминалось, он происходит от CListBox. Все вещи, которые я упомянул в своем посте, относятся именно к CListBox, но из-за деривации они также работают с CCheckListBox.