Главная » Уроки по ООП » Урок 42. Компоненты TDBGrid, TDBCtrlGrid

Урок 42. Компоненты TDBGrid, TDBCtrlGrid

Компонент TDBGrid

TDBGrid - таблица, в которой строки представляют собой записи, а столбцы — поля набора данных. Свойство DataSource содержит ссылку на выбранный набор данных.

Столбцы DBGrid

Столбцы – поля подключенного набора данных. Этими значениями можно манипулировать, показывая или скрывая поля НД, меняя их местами или добавляя новые столбцы. Требуемый набор полей можно составить при помощи специального Редактора столбцов (рис. 1), который открывается при двойном щелчке на компоненте, перенесенном на форму.
В верхней части окна вы видите четыре кнопки, слева - направо:

  1. Add New (Добавить новый столбец).
  2. Delete Selected (Удалить выделенный столбец).
  3. Add All Fields (Добавить все столбцы из набора данных).
  4. Restore Defaults (Восстановить значения по умолчанию для выделенного столбца).


Рис. 1. Редактор колонок компонента TDBGrid
Для выбранного в списке столбца доступные для редактирования свойства появляются в Инспекторе объектов. Столбцы в списке можно редактировать, удалять, менять местами.
Изменить параметры заголовка столбца можно в раскрывающемся свойстве Title, которое имеет ряд собственных свойств:
Alignment - свойство устанавливает выравнивание заголовка и может быть taCenter (по центру), taLeftJustify (по левому краю) и taRightJustify (по правому краю).
Caption - свойство содержит текст, который отображается в заголовке столбца.
Color - цвет заголовка.
Font - шрифт заголовка.
Свойства Font, Alignment и Color внутри свойства Title меняют шрифт, выравнивание и цвет фона только заголовка столбца, а не его содержимого. Но у столбца имеются эти же свойства, они меняют шрифт, выравнивание и цвет фона выводимых в столбце данных.
Свойство Visible разрешает или запрещает отображение столбца, а свойство Width позволяет изменить его ширину.

Задание 1. Работа с редактором полей компонента DBGrid
1. Установите на форму компонент ADOTable, свяжите его с таблицей Pers базы Сотрудники (свойства ConnectionString – связать с базой Сотрудники, TableName=Pers, Active=True).
2. Установите DataSource, свяжите его с ADOTable1. .
3. На форму добавьте и компонент DBGrid, который свяжите с DataSource1..
4. Нам нужны не все поля таблицы, а только некоторые из них. Дважды щелкните по компоненту DBGrid1 и в открывшемся редакторе столбцов нажмите кнопку Add New. Появится один пустой столбец. Для того, чтобы он показал данные нужного поля, выделите его и в инспекторе объектов в свойстве FieldName выберите поле Fam. .
5. Найдите свойство Title, раскройте его нажатием на кнопку «+». Настройте подсвойство Alignment=taCenter, Caption=”Фамилия”, Font установите полужирным. Найдите свойство Width, установите его равным 150. .
6.Аналогично добавьте и настройте свойства полей Nam, Par, Sex, Dep.
.
Рисунок 2. Форма к заданию 1.

Пустые столбцы

Если добавить в редактор столбцов сетки DBGrid новый столбец, но в свойстве FieldName не выбирать поле БД, а оставить его пустым, мы получим пустой столбец. Для чего нужны пустые столбцы в сетке? В них можно выводить обработанные данные из других столбцов.

Задание 2. К примеру, пользователю неудобно просматривать три столбца "Фамилия", "Имя" и "Отчество" из таблицы Pers базы данных Сотрудники. Ему было бы удобней просмотреть один сборный столбец в формате "Фамилия И.О.". .
1. Это и все последующие задания выполнять в программе из задания 1..
2. Создайте новый столбец, но не назначайте ему поле из НД. Выделите этот столбец, и в его свойстве Title.Caption впишите "Фамилия И.О.", а в свойстве Width укажите ширину в 200 пикселей. .
3. Столбцы "Фамилия", "Имя" и "Отчество" нам уже не нужны, скройте их, установив их свойство Visible в False. А новый столбец перетащите мышью наверх, его индекс будет равен 0..
4. Для компонента DBGrid1 создайте обработчик события OnDrawColumnCell. Это событие наступает при прорисовке каждой ячейки столбца. В него внесите код:.

var  s: String;
begin
if Column.Index = 0 then   //если это пустой столбец
begin
if ADOTable1['Fam']<>Null then  s:=ADOTable1['Fam'] + ' ';
if ADOTable1['Nam']<>Null then  s:=s + Copy(ADOTable1['Nam'], 1, 1)+ '.';
if ADOTable1['Par'] <>Null  then  s:=s + Copy(ADOTable1['Par'], 1, 1)  + '.';
DBGrid1.Canvas.TextOut(Rect.Left, Rect.Top, s);
end;
end;

Здесь мы вначале проверяем - наш ли это столбец (равен ли индекс нулю)? Если наш, то в переменную s начинаем собирать нужный текст. При этом имеем в виду, что пользователь мог и не заполнить некоторые поля. Чтобы у нас не произошло ошибки, вначале убеждаемся, что поле не равно Null (то есть, текст есть). Если текст есть, добавляем его в переменную s. Причем если это имя или отчество, с помощью функции Copy() получаем только первую букву и добавляем к ней точку. Когда s сформирована, добавляем этот текст в наш столбец с помощью метода TextOut() свойства Canvas сетки. В метод передаются три параметра: координаты левой позиции, верхней позиции и сам текст. Эти координаты мы берем из параметра события OnDrawColumnCell - Rect, который имеет такие свойства, как Left и Top, показывающие, соответственно, левую и верхнюю позиции текущей ячейки.
В результате программа будет иметь вид:

Рисунок 3.  Заполнение пустого столбца

 

Задание 3. Использовать пустой столбец для вывода информации по требованию пользователя. В DBGrid нам нужна кнопка, нажатие на которую привело бы к выводу сообщения об отделе, в котором работает сотрудник.
1. Откройте редактор столбцов и удалите столбец Dep.
2. Создайте новый пустой столбец. Перетаскивать его не нужно, пусть будет последним. Свойство Width (ширина) установите в 20 пикселей. Название столбца (Title.Caption) пусть будет пустым. В свойстве ButtonStyle выберите значение cbsEllipsis. Это приведет к тому, что при попытке редактировать этот столбец образуется кнопка с тремя точками:

Рисунок 4.  Кнопка в пустом столбце
3. Создайте обработчик события OnEditButtonClick() компонента DBGrid. Это событие происходит всякий раз, когда пользователь нажимает на кнопку "…".

ShowMessage('Отдел: '+ADOTable1['Dep']);

4. Теперь, когда пользователь нажмет на эту кнопку, ему будет выведено сообщение с текстом об отделе, в котором работает сотрудник.

Список выбора в столбце - PickList

DBGrid позволяет устроить список, аналогичный ComboBox в одном из своих столбцов без использования каких-либо других компонентов.

Задание 4. Создать для поля «Sex» список выбора значений (муж, жен).
1. Откройте редактор столбцов сетки и выделите столбец "Sex". Обратите внимание на свойство PickList в Инспекторе объектов. Это свойство имеет тип TStrings, то есть представляет собой набор строк. Щелкните дважды по PickList, чтобы открыть редактор, и впишите туда
муж
жен
именно так, каждое значение на своей строке.
2. Запустите программу и попробуйте редактировать этот столбец. При попытке редактирования в ячейке покажется похожий на ComboBox список, в котором можно будет выбрать одно из указанных значений:

Рисунок 5.  Список выбора в сетке

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

В практике программирования список чаще формируется во время работы программы, а строки списка берутся, как правило, из другой связанной таблицы. Добавить в список новую строку очень просто: DBGrid1.Columns.Items[4].PickList.Add('абв');

Список свойства PickList автоматически заполняется для поля синхронного просмотра (lookup-поле).

Выделение отдельных строк

Очень часто в практике приходится выделять какие-то строки, изменяя их фон или цвет шрифта. Например, в бухгалтерии обычно выделяют строки, в которых значение меньше нуля. Допустим, ваша программа показывает клиентов, а какой-то столбец содержит их баланс на счету вашей компании. Если этот баланс меньше 0, значит, клиент имеет задолженность перед вашей фирмой. Бухгалтеру будет очень удобно, если дебиторы (должники) будут выделяться в общем списке красным цветом.

Способ прорисовки данных в DBGrid зависит от значения его свойства DefaultDrawing. По умолчанию свойство равно True, то есть данные прорисовываются автоматически. Если свойство содержит False, то прорисовку придется кодировать самостоятельно в свойстве OnDrawColumnCell.
Если мы написали алгоритм прорисовки, но свойство DefaultDrawing содержит True, то вначале сетка заполнится данными автоматически, а затем будет выполнен наш алгоритм. Другими словами, прорисовка некоторых частей сетки будет выполнена дважды. Это не очень хорошо для быстродействия программы, однако нам придется поступать именно так: ведь мы не все строки и столбцы собираемся выводить другим способом, а только некоторые. Остальные будут заполнены данными по умолчанию.

Разберем этот метод подробней. Если найти его в справке Delphi, то увидим:

property OnDrawColumnCell: TDrawColumnCellEvent;

То есть, этот метод имеет тип TDrawColumnCellEvent. Описание типа такое:

type TDrawColumnCellEvent = procedure (Sender:TObject; const Rect:TRect;
DataCol:Integer; Column:TColumn; State:TGridDrawState) of object;

Разберемся с параметрами.
Rect - координаты прорисовки.
DataCol - порядковый номер текущего столбца (начиная с 0).
Column - данные текущего столбца.
State - состояние ячейки. Может быть:

  • gdSelected - ячейка выделена
  • gdFocused - фокус ввода в ячейке
  • gdFixed - ячейка - заголовок столбца.

    Задание 5. Изменение цвета шрифта записей сотрудников, относящихся к отделу Бухгалтерия, на красный.

    Рисунок 6.  Выделение строк
    Заметим сразу, что наличие пустых столбцов создает дополнительные, но решаемые проблемы. Код события OnDrawColumnCell придется переделать, он будет таким:

    var s: String;
    begin<
      with DBGrid1.Canvas do begin    //поле "Dep" содержит Бухгалтерия?
       if (ADOTable1['Dep']= 'Бухгалтерия') and not (gdSelected in State)
        then begin   //выводим все ячейки строки красным по белому:
           Font.Color:= clRed;
        FillRect(Rect);
      end; //if
    //если это пустой сборный столбец
     if Column.Index = 0 then begin
       if ADOTable1['fam'] <> Null then s:= ADOTable1['fam'] + ' ';
      if ADOTable1['nam'] <> Null then s:= s + Copy(ADOTable1['nam'], 1, 1) + '.';
         if ADOTable1['par'] <> Null then s:= s + Copy(ADOTable1['par'], 1, 1)+ '.';
        DBGrid1.Canvas.TextOut(Rect.Left, Rect.Top, s);
      end
      else
      if Column.Index = 5 then   //если это пустой столбец с кнопкой "..."
    begin
    DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);
         Exit;
     end
       else TextOut(Rect.Left+2, Rect.Top+2, Column.Field.Text); //все остальные столбцы
    end;
    end;

    Разберемся с кодом. Вначале с помощью with мы указываем, что будем работать непосредственно со свойством DBGrid1.Canvas, которое отвечает за стиль прорисовки ячейки. Далее мы смотрим поле «Dep» текущей записи равно ли Бухгалтерия. Если да, то указываем, что цвет шрифта должен быть красным, а затем функцией FillRect(Rect) мы стираем стандартный вывод.
    Далее мы определяем, прорисовывается ли в данный момент пустой сборный столбец с "Фамилия И.О.". Если это он, то мы формируем переменную s с нужными данными и выводим их, как в прошлый раз.
    Если же это пустой столбец с кнопкой "…", то мы делаем стандартный вывод и выходим из процедуры. Если мы этого не сделаем, то получим ошибку программы.
    Все остальные столбцы мы выводим строкой

    TextOut(Rect.Left+2, Rect.Top+2, Column.Field.Text);

    Обратите внимание, что мы добавили по два пикселя к крайней левой и крайней верхней координате ячейки. Если этого не сделать, то новая прорисовка не будет целиком закрашивать старую (рис.7):

    Рисунок 7.  Некорректная прорисовка
    Количество добавляемых 2пикселей зависит от формата данных и размера шрифта. Обычно это определяется путем проб. Например, ячейка может содержать цифры, которые обычно прижимаются к правому краю, и тут двумя пикселями не обойтись.
    Сделать проверку на тип данных можно, например, так:

    //если текст, сдвинем только на 2 пикселя
    if Column.Field.DataType = ftString then TextOut(Rect.Left, Rect.Top+2, Column.Field.Text)
    //если цифры, сдвинем их вправо на 28 пикселей
    else TextOut(Rect.Left+28, Rect.Top+2, Column.Field.Text);

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

    Font.Color:= clRed;
    FillRect(Rect);

    вам придется написать

    //выводим все ячейки строки белым текстом по красному фону:
    Brush.Color:= clRed;
    Font.Color:= clWhite;
    FillRect(Rect);

    Как видите, подсвойство DBGrid1.Canvas.Brush.Color отвечает за цвет заливки ячейки, а DBGrid1.Canvas.Font.Color за цвет выводимого в ней шрифта.

    Компонент TDBCtrlGrid

    Компонент TDBCtrlGrid (стр.DataControls) внешне напоминает компонент TDBGrid, но никак не связан с классом TCustomDBGrid, а наследуется напрямую от класса TWinControl.
    Этот компонент позволяет отображать данные в строках в произвольной форме. Компонент представляет собой набор панелей, каждая из которых служит платформой для размещения данных отдельной записи набора данных. На панели могут размещаться любые компоненты отображения данных, предназначенные для работы с отдельным полем. С каждым таким компонентом можно связать нужное поле набора данных. При открытии набора данных в компоненте TDBCtrlGrid на каждой новой панели создается набор компонентов отображения данных, аналогичный тому, который был создан на одной панели во время разработки.
    На панель можно переносить только те компоненты отображения данных, которые показывают значение одного поля для единственной записи набора данных. Нельзя использовать компоненты TDBGrid, TDBCtrlGrid, TDBRichEdit, TDBListBox, TDBRadioGroup, TDBLookupListBox.
    Компонент может отображать панели в одну или несколько колонок. Для задания числа колонок панелей используется свойство ColCount. Число видимых строк панелей определяется свойством RowCount. Вертикальное или горизонтальное размещение колонок панелей зависит от значения свойства Orientation.
    Размеры одной панели определяются свойствами panelHeight и Panelwidth. Они взаимосвязаны с размерами самого компонента. При изменении значений свойств PanelHeight и Panelwidth размеры компонента изменяются таким образом, чтобы в нем помещалось указанное в свойствах colcount и RowCount число панелей и наоборот.
    Не рекомендуется размещать на панели компоненты TDBMemo и TDBimage, т. к. это может привести к значительному снижению производительности.

    Задание 6. Работа с компонентом DBCtrlGrid.
    Установите на форму компонент DBCtrlGrid.
    Укажите в его свойстве DataSource ссылку на компонент DataSource1.
    Установите на DBCtrlGrid следующие компоненты (рис.8):
    DBText1 (DataField=fam), DBText2 (DataField=Nam), DBText3 (DataField=Par),
    DBEdit1 (DataField=Dep),
    DBComboBox1 (DataField=Sex, в свойстве Items задайте две строки «муж» и «жен»),
    для слов «Отдел» и «Пол» установите компоненты Label1 и Label2.
    Запустите программу и посмотрите как выглядит компонент DBCtrlGrid (рис.9).

    Рисунок 8. Форма в процессе разработки

    Рисунок 9. DBCtrlGrid после запуска программы

     

     

    Составитель: Салий Н.А.

    Яндекс.Метрика
Сайт создан в системе uCoz