CheckBox in DBGrid

11 отговора 327 прегледа
#1

CheckBox in DBGrid

Как мога да поставя CheckBox в някоя клетка на DBGrid така че като кликна върху CheckBox-a той да сменя състоянието си което да речем се записва в поле от таблица.А дали не може да се използва и DBCheckBox.В книката на Марко Канту Mastering Delphi 5 има подобен пример в I-ва част стр.519 но DBCheckBox-a се показва само когато е селектирана колоната.Аз искам да стои и когато колоната не е селектирана и при кликване върху него да сменя състоянието си.
Моля ако някой добър човек може да помогне нека го направи, като му благодаря предварително

Отговор
в отговор на turtle #2

Re: CheckBox in DBGrid

Опитай да премахнеш /и разучиш какво прави/ събитието DBGridColEnter - показано е на 520 стр.
Има обаче един съществен проблем - в примера е показана работа с ЕДНА отметка. Предполагам че искаш цялата колона да показва отметки. Тогава следва забавна ескалация на проблема:
1. Първата стъпка е да се направят толкова отметки, колкото записа имаме. Това е малко глупаво, понеже записите може да са сочен брой
2. Втората стъпка е да се правят само толкова отметки, колкото се показват на екрана.
3. На трети пас се оказва, че можем да имаме повече от една колонка с отметки.
В крайна сметка, препоръчвам ти да погледнеш и изучиш един хубав пример:
[линк]

чети и дишай по-леко
Отговор
в отговор на Pechenia #3

Re: CheckBox in DBGrid

Аз съм направил в дадена колона да се показва CheckBox във всички клетки като съм направил състоянията на CheckBox-a като Bitmap и ги прерисувам в OnDrawColumnCell в зависимост от съдържанието на поле от таблицата, т.е. ако полето е 0 рисувам UnChecked CheckBox а ако е 1 Ckecked CheckBox.
Ето и малко код само че C++(Работя със C++Builder 6.)

void __fastcall TfrmMain::DBGrid3DrawColumnCell(TObject *Sender,
const TRect &Rect, int DataCol, TColumn *Column,
TGridDrawState State)
{
Graphics::TBitmap *ImSel;
ImSel = new Graphics::TBitmap;
if(Column->FieldName == "Select")
{
DBGrid3->Canvas->Brush->Color = clWhite;
DBGrid3->Canvas->FillRect(Rect);
if(ADOTask->FieldByName("Select")->AsString == '0')
{
ImageList1->GetBitmap(0,ImSel);
}
else
{
ImageList1->GetBitmap(1,ImSel);
}
DBGrid3->Canvas->Draw((Rect.Left+2 + Rect.Right - ImSel->Width)/2,Rect.Top+1, ImSel);
delete ImSel;
}
}

При кликване върху клетката, т.е. върху Bitmap-a(CheckBox) се изпълнява код в събитието OnCellClick.Променя се съдържанието на полето от таблицата което съхранява състоянието на CheckBox-a,и по което поле се изрисува съответното му състояние в клетките на колоната от DBGrid-a.
Ето и съответният код:

void __fastcall TfrmMain::DBGrid3CellClick(TColumn *Column)
{
if(Column->FieldName == "Select")
{
ADOTask->Edit();
if(ADOTaskSelect->AsString == '0')
ADOTaskSelect->AsString = '1';
else
ADOTaskSelect->AsString = '0';
ADOTask->Post();
}
}

Проблема се явява когато е селецтирана дадена клетка, т.е. е във фокус и се кликне с мишката върху нея се появява истинската стойност на полето, т.е. 1 или 0 и полето изпада в състояние Edit().Като се промени фокуса на друга клетка се появява съответния CheckBox(Bitmap-a) в клетката където е била истинската стойност.
Искам когато клетката с CheckBox-a е във фокус и се кликне върху нея да се смени само състоянието а не да се показва истинската стойност.Когато клетката не е във фокус няма проблеми.Състоянието на CheckBox-a Се променя.
Е този проблем не мога да го реша от доста време насам затова го поставям във форума.
Дано някой помогне.

Отговор
в отговор на Pechenia #4

Re: CheckBox in DBGrid

Този пример (DBGridColor)е много хубав и върви на Delphi (тествах го) но във C++Builder не върви.Ще покажа малко код.


На Delphi:

procedure TformColorGrid.DBGridDrawColumnCell(Sender: TObject; const Rect: TRect;DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
Style : Integer;
if Column->FieldName = 'Remainder' then
if ADOSubMats->FieldByName('Remainder')->AsString = '0'
Style := DFCS_CHECKED;
else
Style := DFCS_BUTTONCHECK;
DrawFrameControl(TDBGrid(Sender).Canvas.Handle,Rect,DFC_BUTTON, Style);

end;



еквивалента в C++Builder:

void __fastcall TfrmMain::DBGridSubMatsDrawColumnCell(TObject *Sender,
const TRect &Rect, int DataCol, TColumn *Column,
TGridDrawState State)
{
int Style;
if(Column->FieldName == "Remainder")
if(ADOSubMats->FieldByName("Remainder")->AsString == '0')
Style == DFCS_CHECKED;
else
Style == DFCS_BUTTONCHECK;
DrawFrameControl(dynamic_cast<TDBGrid*>(Sender)->Canvas->Handle,Rect,DFC_BUTTON, Style);
}


Компилатора на C++Builder се оплаква със следната грешка:

Cannot convert 'const TRect to tagRECT*'
Type mismatch in parameter 2(wanted 'tagRECT*',got 'TRect')

Струвами се че описанието на типа TRect в Delphi и C++Builder e различно и не виждам начин да се оправят нещата.Какъв е тоя тип tagRECT?
За първи път се сблъсквам с проблем от този род.Дано да се намери решение.

Отговор
в отговор на turtle #5

Re: CheckBox in DBGrid

Не знам конкретната ситуация - ама аз наскоро открих подобен проблем - в VirtualTreeView - има един event който е дефиниран кофти !!!!- случва се - и като се опитраш да завържеш събитие за него - става кофти - явно е някакво недоглеждане на компилатора на Делфи!!!!
Погледни двата кода - имам предвид в сорса - дали декларациите на събитието не се различават ?! Ако се различават - корегирай С версията - това може да е проблема - макар че от това което и пуснал - не мога да видя проблем. Всъщност -пробвай да махнеш reference оператора пред Rect в параментрите на функцията - това май е видимата разлика?!

---
Е т'ва е живот!
Отговор
в отговор на PhantomAS #6

Re: CheckBox in DBGrid

Работата е в това , че не е там проблема ами това явно е bug.Господата от Borland май са бързали много и са недоогледали нещо.Мисля че е необходимо да им пратим едно e-mail-че.

Отговор
в отговор на Morffei #7

Re: CheckBox in DBGrid

Само, че човека не ползва борландския dbgrid ами Colour Grid ! А иначе подобен проблем не мога да установя, защото почти не ползвам C-Builder ;-))) т.е. дали има разлика между VCL библиотеките за Delphi и CBuilder- би трябвало да няма.

---
Е т'ва е живот!
Отговор
в отговор на PhantomAS #8

Re: CheckBox in DBGrid

До колкото аз разбирам човека ползва точно Borland-ския DBGrid а използва пример наречен Colour Grid.Относно разлика между VCL на C++Builder и Delphi няма такава , защото Builder-а ползва VCL-a на Delphi.Така, че проблема на човека си остава нерешен.

Отговор
в отговор на Morffei #9

Re: CheckBox in DBGrid

Много добре си разбрал.Точно за Борландския DBGrid става въпрос.

Отговор
в отговор на turtle #10

Коя версия на C-Builder използваш?

?.?

---
Е т'ва е живот!
Отговор
в отговор на turtle #11

Re: Ето решение на проблема

Приятел използваи следния код :

void __fastcall TfrmMain::DBGridSubMatsDrawColumnCell(TObject *Sender,
const TRect &Rect, int DataCol, TColumn *Column,
TGridDrawState State)
{
const int CtrlState[] = {DFCS_BUTTONCHECK, DFCS_CHECKED};
TRect CheckBoxRectangle;
if(Column->Field->DataType == ftBoolean)
{
this->DBGridSubMats->Canvas->FillRect(Rect);
CheckBoxRectangle.Left = Rect.Left + 1;
CheckBoxRectangle.Right = Rect.Right - 1;
CheckBoxRectangle.Top = Rect.Top + 1;
CheckBoxRectangle.Bottom = Rect.Bottom - 1;
DrawFrameControl(this->DBGridSubMats->Canvas->Handle,
&CheckBoxRectangle,
DFC_BUTTON,
CtrlState[Column->Field->AsBoolean]);
}
}

Това е решението на проблема.

Отговор
в отговор на Morffei #12

Re: Ето решение на проблема

Благодаря ти Morffei този код наистина работи.

Отговор