Поиск:

Ответ в темуСоздание новой темы Создание опроса
> как реализовать DBGrid с Checкbox 
:(
    Опции темы
Bosh
Дата 7.5.2006, 18:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 7.5.2006

Репутация: нет
Всего: нет



База на SQL 2000 Подключаю с помощью ADO Есть таблицы в которых поля типа булеан
как вывести в DBGrid что бы в нем отображалось как Checкbox и можно было изменять значение 
PM MAIL   Вверх
SPrograMMer
Дата 7.5.2006, 21:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Спамер :)
**


Профиль
Группа: Участник
Сообщений: 442
Регистрация: 5.11.2004
Где: Краснодар

Репутация: 1
Всего: 6



библиотека EhLib компонент TDBTableEh, свойство CheckBoxes=True для столбца и... готово!

Добавлено @ 21:35 
а еще: ПОИСК!!! 


--------------------
животное = зверь
законченный гентушник
PM MAIL ICQ Jabber   Вверх
Fast
Дата 9.5.2006, 06:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 76
Регистрация: 21.3.2006
Где: Санкт-Петербург

Репутация: 1
Всего: 1



Вот стандартный пример из DRKB (Delphi Russian Knowledge Base)!!!

КОМПОНЕНТ #3 - TDBCHECKBOX 
Технология работы с компонентом DBCheckBox более интересна. В этом случае нам необходимо дать понять пользователю о наличие компонента DBCheckBox в ячейках без фокуса. Вы можете вставлять статическое изображение компонента или динамически изменять изображение в зависимости от логического состояния элемента управления. Я выбрал второе. Я создал два BMP-файла - включенный (TRUE.BMP) и выключенный (FALSE.BMP) DBCheckBox. Поместите два компонента TImage на форму, присвойте им имена ImageTrue и ImageFalse и назначьте соответствующие BMP-файлы в свойстве Picture. Да, чуть не забыл: Вам также необходимо поместить на форму два компонента DBCheckbox. Установите набор данных обоих компонентов в DataSource1 и присвойстве свойству Color значение clWindow. Для начала создадим для формы обработчик события onCreate: 


Код

procedure TForm1.FormCreate(Sender: TObject); 
begin 
  DBLookupCombo1.Visible := False; 
  DBCheckBox1.Visible := False; 
  DBComboBox1.Visible := False; 
  ImageTrue.Visible := False; 
  ImageFalse.Visible := False; 
end; 




Теперь нам нужен обработчик события onDrawDataCell чтобы делать что-то с ячейками, не имеющими фокуса. Здесь подойдет следующий код: 


Код

procedure TForm1.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect; 
  Field: TField; State: TGridDrawState); 
begin 
  if (gdFocused in State) then 
  begin 
    if (Field.FieldName = DBLookupCombo1.DataField) then 
    begin 
      // ...СМОТРИ ВЫШЕ 
    end 
    else if (Field.FieldName = DBCheckBox1.DataField) then 
    begin 
      DBCheckBox1.Left := Rect.Left + DBGrid1.Left + 1; 
      DBCheckBox1.Top := Rect.Top + DBGrid1.top + 1; 
      DBCheckBox1.Width := Rect.Right - Rect.Left { - 1}; 
      DBCheckBox1.Height := Rect.Bottom - Rect.Top { - 1}; 
      DBCheckBox1.Visible := True; 
    end 
    else if (Field.FieldName = DBComboBox1.DataField) then 
    begin 
      // ...СМОТРИ ВЫШЕ 
    end 
  end 
  else {в этом месте помещаем статическое изображение компонента} 
  begin 
    if (Field.FieldName = DBCheckBox1.DataField) then 
    begin 
      if TableGridDataCheckBox.AsBoolean then 
        DBGrid1.Canvas.Draw(Rect.Left, Rect.Top, ImageTrue.Picture.Bitmap) 
      else 
        DBGrid1.Canvas.Draw(Rect.Left, Rect.Top, ImageFalse.Picture.Bitmap) 
    end 
  end; 
end; 




Самое интересное место - последний участок кода. Он выполняется в случае, когда состояние не равно gdFocused и сам CheckBox находится в колонке. В нем осуществляется проверка данных поля: если они равны True, то выводится рисунок TRUE.BMP, в противном случае - FALSE.BMP. Предварительно я создал два изображения, представляющие собой "слепок" двух логических состояния компонента, теперь будет очень трудно обнаружить отсутствие компонента в ячейках с фокусом и без оного. Теперь напишем обработчик события onColExit: 



Код

procedure TForm1.DBGrid1ColExit(Sender: TObject); 
begin 
  If DBGrid1.SelectedField.FieldName = DBLookupCombo1.DataField then 
    DBLookupCombo1.Visible := false 
  else 
  If DBGrid1.SelectedField.FieldName = DBCheckBox1.DataField then 
    DBCheckBox1.Visible := false 
  else 
  If DBGrid1.SelectedField.FieldName = DBComboBox1.DataField then 
    DBComboBox1.Visible := false; 
end; 





Организуйте обработку события onKeyPress как показано ниже: 


Код

procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char); 
begin 
  if (key <> chr(9)) then 
  begin 
    if (DBGrid1.SelectedField.FieldName = DBLookupCombo1.DataField) then 
    begin 
      DBLookupCombo1.SetFocus; 
      SendMessage(DBLookupCombo1.Handle, WM_Char, word(Key), 0); 
    end 
    else if (DBGrid1.SelectedField.FieldName = DBCheckBox1.DataField) then 
    begin 
      DBCheckBox1.SetFocus; 
      SendMessage(DBCheckBox1.Handle, WM_Char, word(Key), 0); 
    end 
    else if (DBGrid1.SelectedField.FieldName = DBComboBox1.DataField) then 
    begin 
      DBComboBox1.SetFocus; 
      SendMessage(DBComboBox1.Handle, WM_Char, word(Key), 0); 
    end; 
  end; 
end; 

  


Наконец, последняя хитрость. Для удобства пользователя заголовку компонента нужно присвоить текущее логическое значение. С самого начала у меня была идея поручить это обработчику события onChange, но проблема в том, что событие может возникнуть неединожды. Итак, я должен снова воспользоваться функцией Windows API и послать компоненту соответствующее значение: "SendMessage(DBCheckBox1.Handle, BM_GetCheck, 0, 0)", которая возвращает 0 в случае если компонент невключен и любое другое число в противном случае. 


Код

procedure TForm1.DBCheckBox1Click(Sender: TObject); 
begin 
  if SendMessage(DBCheckBox1.Handle, BM_GetCheck, 0, 0) = 0 then 
    DBCheckBox1.Caption := ' ' + 'Ложь' 
  else 
    DBCheckBox1.Caption := ' ' + 'Истина' 
end; 

  


Это все. Надеюсь, Вы узнали для себя что-то новое. Я пробовал данную технологию с диалоговыми окнами. Делается достаточно просто и великолепно работает. Радует простота реализации. Вам даже не нужно знать как это работает, единственное, что Вам придется - заменить в тексте кода имена вымышленных компонентов на те, которые Вы реально хотите отображать в табличной сетке. 

Ревизия 

Вышеприведенный код оказался несвободным от недостатков - после первой публикации совета дотошные программисты таки обнаружили две значительные недоработки. Первая проблема - если компонент имеет фокус, то для перемещения на следующую ячейку необходимо двукратное нажатие клавиши Tab. Вторая проблема возникает при добавлении новой записи. 






Или Используй компонент DbGridEh из библиотеки EhLib вместо своего грида =)
Мне очень понравился  smile  
PM MAIL   Вверх
Bosh
Дата 11.5.2006, 12:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 7.5.2006

Репутация: нет
Всего: нет



СПАСИБО Попробую разобраться. 
PM MAIL   Вверх
Bosh
Дата 11.5.2006, 12:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 7.5.2006

Репутация: нет
Всего: нет



Подскажите где скачать библиотеку EhLib 
PM MAIL   Вверх
Dynamic
Дата 11.5.2006, 15:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 372
Регистрация: 5.7.2004
Где: Салехард

Репутация: 2
Всего: 15



набери в поисковике EhLib - удивишься 


--------------------
Было бы о чем молчать, а уж что сказать – всегда найдется...
PM MAIL WWW   Вверх
Savek
Дата 11.5.2006, 15:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 355
Регистрация: 10.4.2006
Где: Воронеж

Репутация: 7
Всего: 7



Я не сторонник использования чужих компонентов, поэтому привожу еще вариант решения
Процедура отрисовки чекбокса вызывается если поле если поле имеет логический тип:
Код

procedure TfrmOpenIn.DBGrid1DrawColumnCell(Sender: TObject;
  const Rect: TRect; DataCol: Integer; Column: TColumn;
  State: TGridDrawState);
begin

if Column.Field.DataType=ftBoolean then
  DrawCheckbox(DBGrid1.Canvas,Rect,Column.Field.AsBoolean)
end;



А вот сама процедура

Код

procedure TfrmOpenIn.DrawCheckBox(Canvas: TCanvas; Rect: TRect;
  Checked: boolean);
  var DrawFlags : integer;
       re : TRect;
begin
re:=rect;
re.Top:=re.Top+2;
re.Bottom:=re.Bottom-2;
Canvas.TextRect(Rect,Rect.Left+1,Rect.Top+1,' ');
if Checked then
  DrawFlags:=DFCS_flat or DFCS_CHECKED or DFCS_INACTIVE
else
  DrawFlags:=DFCS_flat or DFCS_INACTIVE;
DrawFrameControl(Canvas.Handle,Re,DFC_BUTTON,DrawFlags);
end;



А вот код для изменения значения щелчком мыши

Код

procedure TfrmOpenIn.DBGrid1CellClick(Column: TColumn);
begin
if Column.Field.DataType=ftBoolean then begin
  with DBGrid1 do begin
  DataSource.DataSet.Edit;
  Column.Field.AsBoolean:=not Column.Field.AsBoolean;
  DataSource.DataSet.Post;
  end;
end;
end;


  
PM MAIL   Вверх
RGirichev
Дата 10.8.2006, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 25
Регистрация: 22.6.2006
Где: Белоруссия

Репутация: нет
Всего: нет



Savek, а можно ли сделать чтобы только при нажатии на сам checkbox он менялся а не на всю строку?
PM WWW ICQ YIM MSN   Вверх
Savek
Дата 10.8.2006, 18:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 355
Регистрация: 10.4.2006
Где: Воронеж

Репутация: 7
Всего: 7



Добавь проверку имени поля, по которомы кликнули

Код

If Column.FieldName:='нужное поле' then begin
....

PM MAIL   Вверх
Akella
Дата 19.8.2006, 09:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 29
Всего: 329



Я не помню, есть ли в MS SQL поля типа Boolean.
Как я делаю в FB.
Создаю поле типа VarChar(1), по умолчанию там значение 'F'.
В гриде, в свойствах столбца есть свойство keylist, типа TStrings, пишу туда:
Цитата

T;t;1;Y;y;
F;f;0;N;n;

т.е. первая строка для True, вторая для False
и в свойствах столбца ставлю CheckBox := True;
всё

а ещё у FIB+ есть понятие "эмуляция полей типа Boolean".
Если в базе FB создать поле типа Int и в названии поля будет присутствовать "BOOLEAN", например "IS_PHOTO_BOOLEAN", то компонента TpFIBDataSet автоматически создат для этого поля столбец в датасете типа TFIBBooleanField, и программист сможет работать с этим столбцом, как нормальным полем типа Boolean.
PM MAIL   Вверх
SergeBS
Дата 22.8.2006, 16:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1111
Регистрация: 10.6.2005
Где: Владимир

Репутация: 11
Всего: 22



Fast, 
Пробовал я этот пример - умучаешься размеры подгонять, и при изменении размера колонки, разрешения - разваливается. И не простой он. А вот способ, описанный Savek работает как надо.
 
Akella, 
Цитата

Я не помню, есть ли в MS SQL поля типа Boolean.

Называется bit. Delphi (ADO) с ним работает как с boolean. Хотя хранятся 0 или 1.
Цитата

и в свойствах столбца ставлю CheckBox := True;

Свойства столбца - чьи, какого компонента? У DBGrid такого нет. Что-то нестандартное применяешь.

Savek, 
Цитата

If Column.FieldName:='нужное поле' then begin

Спешишь. Немного не так:
If Column.FieldName = 'нужное поле' then begin

: -лишнее 
И проверка тоже лишняяsmile. У тебя же CELLclick - уже ячейка а не строка.
PM MAIL   Вверх
student
Дата 26.8.2006, 14:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 26.8.2006

Репутация: нет
Всего: нет



Цитата(Savek @ 11.5.2006,  15:17)
Я не сторонник использования чужих компонентов, поэтому привожу еще вариант решения
Процедура отрисовки чекбокса вызывается если поле если поле имеет логический тип:
Код

procedure TfrmOpenIn.DBGrid1DrawColumnCell(Sender: TObject;
  const Rect: TRect; DataCol: Integer; Column: TColumn;
  State: TGridDrawState);
begin

if Column.Field.DataType=ftBoolean then
  DrawCheckbox(DBGrid1.Canvas,Rect,Column.Field.AsBoolean)
end;



А вот сама процедура

[code=delphi]
procedure TfrmOpenIn.DrawCheckBox(Canvas: TCanvas; Rect: TRect;
  Checked: boolean);
  var DrawFlags : integer;
       re : TRect;
begin
re:=rect;
re.Top:=re.Top+2;
re.Bottom:=re.Bottom-2;
Canvas.TextRect(Rect,Rect.Left+1,Rect.Top+1,' ');
if Checked then
  DrawFlags:=DFCS_flat or DFCS_CHECKED or DFCS_INACTIVE
else
  DrawFlags:=DFCS_flat or DFCS_INACTIVE;
DrawFrameControl(Canvas.Handle,Re,DFC_BUTTON,DrawFlags);
end;




Можно поподробнее где найти DrawCheckbox...чето я догнать не могу (((
PM MAIL   Вверх
Savek
Дата 26.8.2006, 17:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 355
Регистрация: 10.4.2006
Где: Воронеж

Репутация: 7
Всего: 7



Что найти? Код процедуры? Он после слов "А вот и сама процедура"
PM MAIL   Вверх
student
Дата 26.8.2006, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 26.8.2006

Репутация: нет
Всего: нет



В свойствах какого компонента его искать? 
Открыл табицу БД Access c помощью ADOQuery...DBCheckBox на форму закинул связал с столбцом типа Boolean a DrawCheckbox не находит 
PM MAIL   Вверх
Savek
Дата 26.8.2006, 18:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 355
Регистрация: 10.4.2006
Где: Воронеж

Репутация: 7
Всего: 7



Цитата(student @ 26.8.2006,  17:32)
В свойствах какого компонента его искать? 
Открыл табицу БД Access c помощью ADOQuery...DBCheckBox на форму закинул связал с столбцом типа Boolean a DrawCheckbox не находит

???.....???.....
При чем тут DBCheckBox?
Процедура DrawCheckBox всего лишь имитирует его в ячейках сетки
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Базы данных и репортинг"
Vit
Петрович

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами


Обязательно указание:

1. Базы данных (Paradox, Oracle и т.п.)

2. Способа доступа (ADO, BDE и т.д.)


  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • Вопросы по SQL и вопросы по базам данных не связанные с Дельфи задавать здесь

FAQ раздела лежит здесь!


Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Vit, Петрович.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Базы данных и репортинг | Следующая тема »


 




[ Время генерации скрипта: 0.0581 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.