CheckBox в DBGrid - PullRequest
       87

CheckBox в DBGrid

6 голосов
/ 26 января 2012

У меня вопрос, как установить столбец в dbgrid в Delphi 7, который будет с флажками.

Заранее спасибо.

Ответы [ 4 ]

11 голосов
/ 22 сентября 2013

Самый простой и наиболее полный метод, который я тестировал, выглядит следующим образом:

В закрытом разделе вашего устройства, объявите глобальный для сохранения параметров сетки. Он будет использоваться для восстановления после временного отключения редактирования текста при вводе столбца флажка - поскольку это, возможно, одна из небольших ошибок, упомянутых Джорданом Борисовиным в отношении статьи delphi.about.com

private      
  GridOriginalOptions : TDBGridOptions;

В событии OnCellClick, если поле имеет логическое значение, переключить и опубликовать изменение в базе данных

procedure TForm1.DBGrid1CellClick(Column: TColumn);
begin  
  if (Column.Field.DataType=ftBoolean) then
  begin      
    Column.Grid.DataSource.DataSet.Edit;
    Column.Field.Value:= not Column.Field.AsBoolean;
    Column.Grid.DataSource.DataSet.Post;   
  end;
end;

Отрисовка флажка для логических полей сетки

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; 
  DataCol: Integer;      Column: TColumn; State: TGridDrawState);
const
   CtrlState: array[Boolean] of integer = (DFCS_BUTTONCHECK, DFCS_BUTTONCHECK or DFCS_CHECKED) ;
begin
  if (Column.Field.DataType=ftBoolean) then
  begin
    DBGrid1.Canvas.FillRect(Rect) ;
    if (VarIsNull(Column.Field.Value)) then
      DrawFrameControl(DBGrid1.Canvas.Handle,Rect, DFC_BUTTON, DFCS_BUTTONCHECK or DFCS_INACTIVE)
    else
      DrawFrameControl(DBGrid1.Canvas.Handle,Rect, DFC_BUTTON, CtrlState[Column.Field.AsBoolean]); 
  end;
end;

Теперь в новой части отключите редактирование ячеек, находясь в логическом столбце. В событиях OnColEnter и OnColExit:

procedure TForm1.DBGrid1ColEnter(Sender: TObject);
begin
  if Self.DBGrid1.SelectedField.DataType = ftBoolean then
  begin
    Self.GridOriginalOptions := Self.DBGrid1.Options;
    Self.DBGrid1.Options := Self.DBGrid1.Options - [dgEditing];
  end;
end;

procedure TForm1.DBGrid1ColExit(Sender: TObject);
begin
  if Self.DBGrid1.SelectedField.DataType = ftBoolean then
    Self.DBGrid1.Options := Self.GridOriginalOptions;
end;

Более того, используйте клавишу пробела для переключения флажка

procedure TForm1.DBGrid1KeyDown(Sender: TObject; var Key: Word;  Shift: TShiftState);
begin
  if ((Self.DBGrid1.SelectedField.DataType = ftBoolean) and (key = VK_SPACE)) then
  begin
    Self.DBGrid1.DataSource.DataSet.Edit;
    Self.DBGrid1.SelectedField.Value:= not Self.DBGrid1.SelectedField.AsBoolean;
    Self.DBGrid1.DataSource.DataSet.Post;   
  end;      
end;

Вот и все!

1 голос
/ 03 января 2014

Прошу прощения за публикацию этого ответа, у меня пока нет 50 репутации, чтобы добавлять комментарии.

Mihai MATEI ответ очень близок к редкому (как в действительно работающем) решении, за исключением случая использования, в котором он содержит ошибки.

Всякий раз, когда первое действие пользователя в сетке состоит в том, чтобы щелкнуть по флажку, первый щелчок будет работать, но второй откроет основной редактор DBGrid.

Это происходит потому, что механизм "GridOriginalOptionsmechan" необходимо инициализировать. Для этого просто добавьте следующий код в событие OnEnter сетки:

procedure TForm1.DBGrid1Enter(Sender: TObject);
begin
  DBGrid1ColEnter(Sender);
end;

Вот и все!

1 голос
/ 27 января 2012

Если вы используете TClientDataset + TDatasetProvider + TDataset, вы можете манипулировать вариантом массива данных, прежде чем он попадет в набор данных клиента, и включить не обновляемое логическое поле.

После того, как все будет сделано, все, что вам нужно, эторисовать на сетке, используя событие OnDrawColumnCell.Здесь я не использовал CheckBox, а просто растровое изображение (когда пользователь щелкает, оно меняется на выбранный / невыбранный).

0 голосов
/ 27 января 2012

ОК, я использовал эту статью для моей проблемы.ОК Но проблема в том, что это не сработало так, как должно.Поэтому я изменяю свою логику в коде.И реализуем это путем сохранения выбранных строк из dbgrid в списке.

...