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

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

Внешний вид

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

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

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

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

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

procedure TMoneyMoveDetailForm.TableViewStylesGetContentStyle(
Sender: TcxCustomGridTableView; ARecord: TcxCustomGridRecord;
AItem: TcxCustomGridTableItem; out AStyle: TcxStyle);
begin
if (ARecord.Values[TableViewID_MONEY.Index])=null then begin
AStyle :=cxStyleBold;
end;
end;

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

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);
<strong>ACanvas.DrawImage</strong>(ImageList,r.Left,r.Top,20,True);
ADone := True ;
end;
end;

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

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 ..»

TableView.OptionsView.GroupByBox := false;

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

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;

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

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

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

 

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

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

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

TableView1.GetColumnByFieldName('FIELD_NAME')

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

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

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

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

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

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:

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

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

if (Sender as TcxCheckBox).Checked then

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

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

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

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

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

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

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.##';

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

TableView.Columns[i].Destroy;

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

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

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

  1. pashagoldenberg говорит:

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

    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 не будет опубликован. Обязательные поля помечены *