C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[42086] Re:DBGrid 에 DBCheckbox 넣기
박지훈.임프 [cbuilder] 2080 읽음    2005-10-05 20:37
디비그리드 위에 디비체크박스를 올려서 처리한다면 그리 깔끔한 결과가 나오기 힘듭니다.
이것저것 예상치 않은 동작들이 나타날 텐데, 그런 부분들을 다 처리하려면 코딩 양도 엄청 많아지고요.

보여주신 소스에서는 현재 레코드에는 디비 체크박스를 하나 올리고 나머지 로우들은 OnDrawColumnCell 이벤트에서
그리는 방식을 썼는데, 여러가지 예상치 않은 결과가 나올 것입니다. 예를 들어 디비그리드에서 현재 레코드가 아닌 다른
레코드의 체크박스 셀을 클릭하면 어떻게 나오나요? 정확히 예상하긴 힘들지만 아마 예상한 것과는 다른 황당한 결과가
나올 것입니다. 또 디비 그리드가 스크롤될 때도 체크박스를 따라서 움직여줘야 할 수도 있고, 다른 부작용들도 한두가지가
아닙니다.

제가 여러가지 방법으로 시도해봤을 때 가장 깔끔한 방식은 현재 레코드이든지 아니든지 무조건 OnDrawColumnCell
이벤트에서 처리해주고, 클릭했을 때는 OnCellClick 이벤트에서 처리해주는 것입니다. 실제 TCheckBox나 TDBCheckBox
컴포넌트는 쓰지 않고요.

다음은 제가 쓰고 있는 델파이 프로젝트의 코드를 C++빌더로 컨버팅한 것입니다.

void __fastcall TForm1::DBGrid1CellClick(TColumn *Column)
{
    if(ClientDataSet1->Eof && ClientDataSet1->Bof) return;
    if(Column->Title->Caption=="입력상태")
    {
        AnsiString NewState;
        if(Column->Field->Text=="1") NewState = "2";
        else                         NewState = "1";
        ClientDataSet1->Edit();
        Column->Field->Text = NewState;
        ClientDataSet1->Post();
    }
}

void __fastcall TForm1::DBGrid1DrawColumnCell(TObject *Sender,
      const TRect &Rect, int DataCol, TColumn *Column, TGridDrawState State)
{
    if(Column->Field!=NULL && Column->Title->Caption=="입력상태")
    {
        TPoint pt = Point((Rect.Left+Rect.Right) / 2 - 6, (Rect.Top+Rect.Bottom) / 2 - 6);
        TRect R(pt.x, pt.y, pt.x+13, pt.y+13);
        DWORD DrawState = DFCS_BUTTONCHECK;
        if(Column->Field->Text=="1") DrawState = DrawState | DFCS_CHECKED;
        DrawFrameControl(DBGrid1->Canvas->Handle, &R, DFC_BUTTON, DrawState);
    }
}

여기서 ClientDataSet1이 디비그리드와 연결된 데이터셋입니다. 그리고 체크박스로 나오는 필드는 저희 회사 디비의 실제
값은 문자열 "1" 혹은 "2" 값입니다. 따라서 불린 형태의 값을 가지는 필드에 연결하시려면 Text가 "1"인가 2인가 여부를
검사하거나 세팅하는 부분을 AsBoolean으로 변경하시면 됩니다.

그럼...


최진호 님이 쓰신 글 :
: DB프로그램을 만들고 있는데 이해가 안되는 부분이 있어서 이렇게 물어 봅니다..
:
: DBGrid 위에 DBCheckBox 와 ADOQuery를 하나 놓고 실행 시키는 프로그램 으로
:
: DBGrid에 DBCheck box를 넣는것 입니다..델파이의 소스를 찾아서 일부를 수정했는데... 이상하게 DBCheckBox에 클릭을 하면 색깔이 바로 변하지 않고 두번 클릭해야 변화가 되고 업데이트가 가능하던데 이런 문제는 어떤식으로 처리 해야 되나요!!!!(마우스 오른쪽 버튼을 클릭하고 다시 윈쪽 버튼을 클릭해야 수정이 가능하게 DBnavigator 버튼이 변하게 됩니다.)
:
:
:
:
:
: #include <vcl.h>
: #pragma hdrstop
:
: #include "Unit1.h"
: //---------------------------------------------------------------------------
: #pragma package(smart_init)
: #pragma resource "*.dfm"
: TForm1 *Form1;
: //---------------------------------------------------------------------------
: __fastcall TForm1::TForm1(TComponent* Owner)
:         : TForm(Owner)
: {
: }
: //---------------------------------------------------------------------------
:
: void __fastcall TForm1::Button1Click(TObject *Sender)
: {
:     ADOQuery1->Close();
:     ADOQuery1->SQL->Clear();
:     ADOQuery1->SQL->Add("SELECT * FROM Articles");
:     ADOQuery1->Open();
: }
: //---------------------------------------------------------------------------
:
: void __fastcall TForm1::FormCreate(TObject *Sender)
: {
:  DBCheckBox1->DataSource = DataSource1;
:  DBCheckBox1->DataField  = "Winner";
:  DBCheckBox1->Visible    = False;
:  DBCheckBox1->Color      = DBGrid1->Color;
:  DBCheckBox1->Caption    = "";
:  //explained later in the article
:  DBCheckBox1->ValueChecked = "출고";
:  DBCheckBox1->ValueUnchecked = "미출고";
: }
: //---------------------------------------------------------------------------
: void __fastcall TForm1::DBGrid1DrawColumnCell(TObject *Sender,
:       const TRect &Rect, int DataCol, TColumn *Column,
:       TGridDrawState State)
: {
:
: const bool  ISChecked[]=
:       {int(DFCS_BUTTONCHECK), int(DFCS_BUTTONCHECK)||int(DFCS_CHECKED)};
: int DrawState;
: TRect DrawRect;
:
:  if(State.Contains(Grids::gdFocused))
:      {
:          if (Column->Field->FieldName == DBCheckBox1->DataField) {
:                         DBCheckBox1->Left = Rect.Left + DBGrid1->Left + 27;
:                         DBCheckBox1->Top = Rect.Top + DBGrid1->Top+2;
:                         DBCheckBox1->Width = Rect.Right - Rect.Left;
:                         DBCheckBox1->Height = Rect.Bottom - Rect.Top;
:                         DBCheckBox1->Visible = true; }
:   
:
:       }
:
: else
:       {
:             if (Column->Field->FieldName == DBCheckBox1->DataField) {
:                         DrawRect=Rect;
:                         InflateRect( (RECT *)(&DrawRect),-1,-1);
:                         DrawState = ISChecked[Column->Field->AsBoolean];
:                         DBGrid1->Canvas->FillRect(Rect);
:                         DrawFrameControl(DBGrid1->Canvas->Handle, (RECT *)(&DrawRect),
:                         DFC_BUTTON, DrawState); }
:       }
:
: }
: //---------------------------------------------------------------------------
: void __fastcall TForm1::DBGrid1ColExit(TObject *Sender)
: {
: if (DBGrid1->SelectedField->FieldName == DBCheckBox1->DataField)
:     DBCheckBox1->Visible = false;
: }

+ -

관련 글 리스트
42069 DBGrid 에 DBCheckbox 넣기 최진호 1291 2005/10/04
42086     Re:DBGrid 에 DBCheckbox 넣기 박지훈.임프 2080 2005/10/05
42100         박지훈.임프 님( 답변 정말 감사합니다..^^) 그럼 수고하세요 최진호 1511 2005/10/06
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.