void __fastcall TForm1::clbClickCheck(TObject *Sender)
{
if(clb->State[clb->ItemIndex]==cbChecked)
{
if(clb->Tag!=-1)clb->State[clb->Tag] = cbUnchecked;
clb->Tag = clb->ItemIndex;
}
else
clb->Tag = -1;
}
TCheckListBox
Подскажите, как сделать так, чтобы в TCheckListBox можно в любой момент времени выбирать только одно значение т.е. запретить множественный выбор.
Переопределить событие OnClickCheck
Код:
[COLOR=black][FONT=Verdana]Что-то с этим компонентом у меня тупик... в голове :) [/FONT][/COLOR][COLOR=black][FONT=Verdana][/FONT][/COLOR]
[COLOR=black][FONT=Verdana]Не могу среди методов найти тот, который удаляет строку из него с нужным индексом. Например, как удалить строку, если она пустая?[/FONT][/COLOR][COLOR=black][FONT=Verdana][/FONT][/COLOR]
Код:
for (int i = 0; i<CheckListBox1->Count; i++)
{
if(CheckListBox1->Items->Strings=="")
{
//удалить
}
}
{
if(CheckListBox1->Items->Strings=="")
{
//удалить
}
}
Код:
for (int i = clb->Count-1; i>=0; i--)
{
if(clb->Items->Strings=="")
{
clb->Items->Delete(i);
}
}
{
if(clb->Items->Strings=="")
{
clb->Items->Delete(i);
}
}
Что-то я сегодня совсем плохая .:rolleyes:
Видимо сказывается что уже пятница и думаю о выходных. :)
А не проще использовать TRadioGroup?
Просто раньше не приходилось сталкиваться с TCheckListBox. Вот решила ознакомиться с компонентом, его возможности и т.п.
С помощью Мerlin, вроде разобралась. :)
P.S. Реализация запрета множественного выбора у Мerlin весьма своеобразная. Я бы так не догадалась. Как еще можно запретить множественный выбор. Просто интересно в плане развития :)
Код:
[LEFT]void __fastcall TForm1::clbClickCheck(TObject *Sender)
{
if(clb->State[clb->ItemIndex]==cbChecked)
{
if(clb->Tag!=-1)clb->State[clb->Tag] = cbUnchecked;
clb->Tag = clb->ItemIndex;
}
else
clb->Tag = -1;
}[/LEFT]
{
if(clb->State[clb->ItemIndex]==cbChecked)
{
if(clb->Tag!=-1)clb->State[clb->Tag] = cbUnchecked;
clb->Tag = clb->ItemIndex;
}
else
clb->Tag = -1;
}[/LEFT]
Если начать щелкать на последней видимой надписи в TCheckListBox в момент скролла, то снова начинается множественный выбор. :mad:
Так может, не стоит все-таки иметь лишний геморрой на свою задницу, а воспользоваться специально предназначенным для выбора одиночного элемента компонентом - TListBox или TRadioGroup?
Я понимаю, конечно, что учиться приемам программирования тоже когда-то надо, но если это становится препятствием на пути реализации проекта - опыты стоит перенести на более подходящее время.
TListBox это просто набор строк без возможности ставить галочки.
Код:
class TForm1 : public TForm
{
__published: // IDE-managed Components
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
void __fastcall MyClickCheck(TObject *);
};
{
__published: // IDE-managed Components
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
void __fastcall MyClickCheck(TObject *);
};
Код:
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
CheckListBox1->OnClickCheck = MyClickCheck;
}
: TForm(Owner)
{
CheckListBox1->OnClickCheck = MyClickCheck;
}
Код:
void __fastcall TForm1::MyClickCheck(TObject *Sender)
{
int ind;
bool state;
if (CheckListBox1->ItemIndex != -1){
ind = CheckListBox1->ItemIndex;
state = CheckListBox1->Checked[ind];
for(int i=0; i < CheckListBox1->Count; i++){
CheckListBox1->Checked = false;
}
CheckListBox1->Checked[ind] = state;
}
}
{
int ind;
bool state;
if (CheckListBox1->ItemIndex != -1){
ind = CheckListBox1->ItemIndex;
state = CheckListBox1->Checked[ind];
for(int i=0; i < CheckListBox1->Count; i++){
CheckListBox1->Checked = false;
}
CheckListBox1->Checked[ind] = state;
}
}
Cпасибо. Этот код работает без сбоев. Я его просто поместила в обработчик щелчка. Без назначения [COLOR=#0000bb]OnClickCheck.[/COLOR]
Код:
[LEFT]void __fastcall TForm1::clbClickCheck(TObject *Sender)
{
if(clb->State[clb->ItemIndex]==cbChecked)
{
if(clb->Tag!=-1)clb->State[clb->Tag] = cbUnchecked;
clb->Tag = clb->ItemIndex;
}
else
clb->Tag = -1;
}[/LEFT]
{
if(clb->State[clb->ItemIndex]==cbChecked)
{
if(clb->Tag!=-1)clb->State[clb->Tag] = cbUnchecked;
clb->Tag = clb->ItemIndex;
}
else
clb->Tag = -1;
}[/LEFT]
Если начать щелкать на последней видимой надписи в TCheckListBox в момент скролла, то снова начинается множественный выбор. :mad:[/QUOTE]Такое может быть, только если сбоит комп или компилятор. :)
Или пред пост относился к моему коду? Если его поместить вместо onClickCheck в OnClick, тогда может такое быть.
Ставим галочку.
Теперь надо поместить курсор на последней видимой в этот момент записи в СheckBox-e. Двигаем мышь слегка вниз и щелкаем на этой надписи. В результате появляется вторая галочка.
Код от SABROG не приводит к появлению второй галочки. ;)
Ставим галочку.
Теперь надо поместить курсор на последней видимой в этот момент записи в СheckBox-e. Двигаем мышь слегка вниз и щелкаем на этой надписи. В результате появляется вторая галочка.
Код от SABROG не приводит к появлению второй галочки. ;)[/QUOTE]Споймал момент. :). Imho аномальное явление, точнее баг, ведь согласно help событие OnClickCheck имеет место, когда
... the user selects or deselects an item’s check box.
В этом случае, ни то, ни другое не происходит, но событие вызывается.
Это можно исправить, но в TCheckListBox есть еще один баг. Чтоб его заметить, нужно отключить обработчик OnClickCheck, и предварительно ничего не выделяя щелкнуть ниже последнего видимого item, под квадратиком. Будет выделена совсем не та запись. Код SABROG-a исправляет этот баг.
[FONT=Arial] [/FONT]
[FONT=Arial]P.S.[/FONT]
[FONT=Arial]Как добавить горизонтальный скролл в CheckListBox если надпись большая?[/FONT]
[FONT=Arial] [/FONT]
[FONT=Arial]P.S.[/FONT]
[FONT=Arial]Как добавить горизонтальный скролл в CheckListBox если надпись большая?[/FONT][/QUOTE]Напр. CheckListBox1->ScrollWidth = CheckListBox1->Width + 200;
Хотя наверно лучше, посредтвом GetTextExtentPoint32() сперва определить длину в пикселах, наибольшей строки.
Код:
int Width, MaxWidth=0;
for (int i=0;i < CheckListBox1->Items->Count;i++)
{
Width = CheckListBox1->Canvas->TextWidth(CheckListBox1->Items->Strings+"x");
if (MaxWidth < Width)
{
MaxWidth = Width;
}
}
SendMessage(CheckListBox1->Handle, LB_SETHORIZONTALEXTENT, MaxWidth, 0);
for (int i=0;i < CheckListBox1->Items->Count;i++)
{
Width = CheckListBox1->Canvas->TextWidth(CheckListBox1->Items->Strings+"x");
if (MaxWidth < Width)
{
MaxWidth = Width;
}
}
SendMessage(CheckListBox1->Handle, LB_SETHORIZONTALEXTENT, MaxWidth, 0);
Cпасибо, [COLOR=#0000bb]SendMessage[/COLOR] работает!
Спасибо.
или
SendMessage(clb->Handle, LB_SETHORIZONTALEXTENT, 0, 0);
или
SendMessage(clb->Handle, LB_SETHORIZONTALEXTENT, 0, 0);[/quote]
Спасибо! Все ОК!
В обработчик onClickCheck пишем: CheckListBox1->CheckAll(0, false, false);
Ну и дальше боремся с ненужными эфектами(у кого какие).
Зачем писать функции если они уже для нас написаны? Думаете напишете оптимаьнее? Сомневаюсь
В обработчик onClick пишем:
CheckListBox1->CheckAll(0, false, false);
for (int i = 0; i < CheckListBox1->Count; i++) {
if (CheckListBox1->Selected) {CheckListBox1->Checked = true;
}
}