Шпаргалка по DevExpress cxGrid и Delphi 7

Некоторые приемы работы с компонентом cxGrid, собранные из разных источников и полезные лично мне. (Обновлено 25.01.2017)

Внешний вид

Программную раскраску ячеек можно делать в событиях OnCustomDrawCell

1
2
3
4
if (AViewInfo.GridRecord.Values[TableViewColumn1.Index])=1 then begin
  ACanvas.Brush.Color := clRed;
  ACanvas.Font.Style := [fsBold];
end;

Если требуется закрасить только отдельные колонки (а не всю строку), то раскрашиваемую колонку в обработчике OnCustomDrawCell можно определить так:

1
if TableView.Columns[AViewInfo.Item.Index].DataBinding.FieldName='COLUMN_1' then

Единственно нужно учитывать что подобная раскраска не выводится при экспорте в Excel а также бывает неудачно выбирается цвет выделения. Для этого нужно красить исключительно присваивая заранее определенный “стиль” в обработчиках типа “TableViewStylesGet***Style”:

1
2
3
4
5
6
7
8
procedure TMoneyMoveDetailForm.TableViewStylesGetContentStyle(
Sender: TcxCustomGridTableView; ARecord: TcxCustomGridRecord; AItem: TcxCustomGridTableItem; out AStyle: TcxStyle);
begin
  if not ARecord.IsData then Exit;
  if (ARecord.Values[TableViewID_MONEY.Index])=null then begin
    AStyle :=cxStyleBold;
  end;
end;

Вывод изображения или иконки в ячейке

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
procedure TMsgForm.TableViewIMAGECustomDrawCell(Sender: TcxCustomGridTableView; ACanvas: TcxCanvas; AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);
Var
  r : TRect;
  iImageIndex : Integer;
begin
  If (AViewInfo.GridRecord.Values[TableViewIMAGE.Index] = 1) then begin
    R := AViewInfo.Bounds;
    ACanvas.Brush.Color := AViewInfo.Params.Color;
    ACanvas.FillRect(R);

// draw the image.
    R := AViewInfo.Bounds;
    Inc(r.Top,1);
    ACanvas.DrawImage(ImageList,r.Left,r.Top,20,True);
    ADone := True ;
  end;
end;

Раскраска разных уровней группировки разным цветом

1
2
3
4
5
6
procedure TPozSkladForm.TableViewStylesGetGroupStyle( Sender: TcxGridTableView; ARecord: TcxCustomGridRecord; ALevel: Integer; out AStyle: TcxStyle);
begin
  if ALevel=0 then AStyle := cxStyleL0;  // $00A0A0A0
  if ALevel=1 then AStyle := cxStyleL1;  // clSilver
  if ALevel=2 then AStyle := cxStyleL2;  // $00E0E0E0
end;

Обратите внимание! При доступе к данным строки через GridRecord и индексу столбца можете не получить ожидамых значений в случае группировки сток, когда отрисовываемая строка окажется строкой заголовка группы.

Отображение данных (фильтры, группировки, сортировки)

В TcxGrid скрыть группировку GroupByBox и убрать область над гридом в которой написано «drag a column header here to group by ..»

1
TableView.OptionsView.GroupByBox := false;

Программно задать фильтр

1
2
3
4
5
TableView.DataController.Filter.BeginUpdate;
TableView.DataController.Filter.Root.Clear;
TableView.DataController.Filter.Root.AddItem(TableViewColumn1, cxFilter.foLike, BegString+"%", BegString+"%");
TableView.DataController.Filter.Active:=true;
TableView.DataController.Filter.EndUpdate

Причем если добавляется более одного условия, то перед добавлением очередного желательно указать булевый тип (по умолчанию будет AND), но можно сделать OR — TableView.DataController.Filter.Root.BoolOperatorKind := fboOr;

Доступ к данным и метаданным грида

 пробежаться в цикле по всем видимым строкам:

1
2
for I:=0 to cxGrid.DataController.FilteredRecordCount - 1 do begin
  cxGrid.DataController.Values[cxGrid.DataController.FilteredRecordIndex[i],YourColumnName.Index])

 

Цикл по всем выделенным строкам с получением идентификатора каждой

1
2
3
for i := 0 to GridView1.Controller.SelectedRecordCount-1 do begin
ID_RASHODD := GridView1.DataController.Values[GridView1.Controller.SelectedRecords[i].RecordIndex, GridView1ID_RASHODD.Index];
end;

Получить колонку грида по ее имени

1
TableView1.GetColumnByFieldName('FIELD_NAME')

 Редактирование данных пользователем

Организация списка ComboBox в ячейке:

в Properties ставим  ComboBox, заполняем список при событиях AfterScroll датасета, если это пытаться делать в onInitPopUp то список вываливается предыдущий (в комментариях подсказали что я делал не правильно). Пример заполнения:

1
2
3
4
5
TcxComboBoxProperties(TableViewCNAME.Properties).Items.Clear;
while not LookupQuery.Eof do begin
TcxComboBoxProperties(TableViewCNAME.Properties).Items.Add(LookupQuery['CNAME']);
LookupQuery.Next;
end;

выбор пользователя проверяется и используется в методе OnValidate примерно так:

1
2
3
4
5
6
7
8
9
10
if LookupQuery.Locate('CNAME',DisplayValue,[]) then begin
// тут заносим в базу
TableView.BeginUpdate;
// тут обновляем таблицу, если нужно
TableView.EndUpdate;
end else begin
ErrorText := 'Ошибка выбора';
Error := True;
end;
TcxComboBoxProperties(TableViewCNAME.Properties).Items.Clear;

Редактирование числа в гриде:

в Properties ставим CalcEdit а в обработчике OnEditValueChanged юзаем (Sender as TcxCalcEdit).Value и текущее положение в датасете

Отловить правый клик на определенной колонке:

в событии OnCellClick:

1
2
if ACellViewInfo.Item.Name='DzTableViewNRM_NAME' then
if AButton=mbRight then

Обработка отметки чек-бокса в ячейке. В событии OnChange:

1
if (Sender as TcxCheckBox).Checked then

Узнать в какой колонке происходит редактирование:

TableView.VisibleColumns[TableView.Controller.FocusedColumnIndex].DataBinding.FieldName

Изменение соседних ячеек при обработке редактирования в  OnEditValueChanged:

TableView.DataController.SetEditValue(TableViewFIELD_NAME.Index, new_Value, evsValue );

 Изменение таблицы в рантайме

Добавление колонки в рантайме:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var
  XCol : TcxGridDBBandedColumn;
begin
  XCol := TableView.CreateColumn;
  XCol.Position.BandIndex := 1;
  XCol.DataBinding.FieldName:='quant'+sl[i];
  XCol.DataBinding.ValueType := 'Float';
  XCol.Caption := ss[i];
  XCol.Width := 50;
  XCol.Tag := StrToInt(sl[i]);
  XCol.Summary.FooterKind := skSum;
  XCol.Summary.GroupFooterKind := skSum;
  XCol.Summary.GroupKind := skSum;
  XCol.Summary.FooterFormat := '0.##';
  XCol.Summary.GroupFooterFormat := '0.##';
  XCol.Summary.GroupFormat := '0.##';

Удаление колонки в рантайме:

1
TableView.Columns[i].Destroy;

Добавление бандов (bands):

1
2
b0 := TableView.Bands.Add;
b0.Position.BandIndex := b.Index;
Запись опубликована в рубрике Без рубрики. Добавьте в закладки постоянную ссылку.

Один комментарий: Шпаргалка по DevExpress cxGrid и Delphi 7

  1. pashagoldenberg

    Спасибо вам за статью.
    Но есть замечание относительно пункта «Редактирование данных пользователем», подпункт «Организация списка ComboBox в ячейке». На самом деле в OnInitPopup тоже можно сделать выпадающий список и он будет актуальным, нужно просто обращаться не к столбцу, а к Sender’-у. Что-то типа этого:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    procedure TrdbXXX.YYYPropertiesInitPopup(
      Sender: TObject);
    begin
      if XQuery.Active then
      begin
        (Sender as TcxComboBox).Properties.Items.Clear;
        XQuery.First;
        while notXQuery.Eof do
        begin
          (Sender as TcxComboBox).Properties.Items.Add(XQuery['FieldName']);
          XQuery.Next;
        end;
      end;
    end;

    a7in: Спасибо за замечание!

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *