Delphi programming blog
Источник: http://teran.karelia.pro/articles/item_4492.html
 

Анонимные методы для заполнения заголовков таблиц

Опубликовано 09.10.2011 г. 22:31

Часто ли вам приходится настраивать таблицу TStringGrid и ей подобные в коде? В моей работе, например, часто бывают такие ситуации. На форме размещен одна таблица TStringGrid, и несколько кнопок действий. Каждая кнопка по своему заполняет таблицу. В итоге в каждом методе обработчике нажатия кнопки приходится писать в основном одинаковый код для установки размеров таблицы и заполнения заголовков строк и столбцов.

Конечно можно решать эту проблему разными способами. Можно вообще не решать и в каждом обработчике нажатия кнопки менять таблицу. Можно, например, добавить метод заполнения таблицы вида:
procedure FillHeaders(sender : TObject);
var c,r : integer;
begin
   if Sender = Button1 then begin
      myGrid.colCount := 5;
      myGRid.rowCount := 10;
      for i := 0 to 4 do myGrid.Cells[i, 0] := 'col' + IntToStr(i);
   end;
   if Sender = Button2 then begin
       .....
   end;
end;
Ну или можно завести отдельный метод для заполнения каждой из таблиц. Мне вот недавно почему то придумался вариант с использованием анонимных методов. Функционал по установке числа строк столбцов и непосредственно назначения заголовков можно вынести в отдельный клаcс/запись. В итоге от нас потребуется только пара методов получения заголовка по его индексу для строки и столбца. Для работы можно создать запись использующую классовые переменные и методы:
    TGridHeaders = record
      strict private
        class var FGrid : TStringGrid;
      public
        type THeaderProc = reference to function(const index : integer): string;

        class procedure Update(const colCount, rowCount : integer;
                         ColProc : THeaderProc = nil; RowProc : THeaderProc = nil); static;

        class procedure Clear(); static;
        class property Grid : TStringGrid read FGrid write FGrid;
    end;
Запись имеет классовое свойство Grid и соответствующую переменную член класса. Сигнатура анонимного метода вынесена в отдельный тип - THeaderProc. Для обновления состояния таблицы используется метод Update:
class procedure TGridHeaders.Update(const colCount, rowCount: integer;
        ColProc : THeaderProc = nil; RowProc : THeaderProc = nil);
var c,r : integer;
begin
    if not assigned(FGrid) then exit;

    try
        FGrid.ColCount := colCount;
        FGrid.RowCount := rowCount;

        for c := 0 to colCount - 1 do begin
            if assigned(ColProc) then
                 FGrid.Cells[c,0] := colProc(c)
            else FGrid.Cells[c,0] := IntToStr(c);
        end;

        for r := 1 to rowCount - 1 do begin
            if assigned(RowProc) then
                 FGrid.Cells[0,r] := RowProc(r)
            else FGrid.Cells[0,r] := IntToStr(r);
        end;
    except
        raise;
    end;
end;
Метод имеет только два обязательных параметра - количество строк и столбцов, да и то, возможно они не требуются. Для заполнения заголовков строк и столбцов и используются переданные анонимные методы. А в случае если они не переданы, то столбцы/строки просто нумеруются. Теперь в обработчиков нажатий кнопок нужно определить эти самые методы, если они, конечно, нужны, и вызвать метод обновления таблицы.
procedure TTestForm.Button1Click(Sender: TObject);
var cp : TGridHeaders.THeaderProc;
begin
    cp := function(const col : integer):string
          begin
              result := Format('Column %d', [col]);
          end;
    TGridHeaders.Update(10,10, cp);
end;
Данный метод устанавливает размеры таблицы в 10 строк и столбцов. Для заполнения заголовков столбцов используется определенная функция. Строки нумеруются по умолчанию.
procedure TTestForm.Button2Click(Sender: TObject);
const rowsCount = 4;
      rowHeaders : array[0..rowsCount - 1] of string = ('','строка 1','стр. 2','стр.3');
var rp : TGridHeaders.THeaderProc;
begin
    rp := function(const row :integer):string
          begin
            result := rowHeaders[row];
          end;

    TGridHeaders.Update(10, rowsCount,
            function(const col : integer):string
            begin
                result := Char(Ord('A')+ col);
            end,
            rp);
end;
В этом методе заголовки строк определены в виде массива констант. Метод для заполнения строк задан в виде переменных, а для заполнения столбцов передается сразу в параметре вызова метода Update(). Конечно, о применимости данного способа для заполнения гридов можно поспорить. Скорее это просто вариант применения анонимных методов для подобных целей.
Метки:  anonymous methods 

Комментарии

karoziya
11.10.2011 в 08:06
Статьи интересные и как то хочется сказать автору, что полезные вещи он пишет, но на все статьи коментов не напишешь. Может сделать кнопочку "мне статья понравилась", я бы ее нажимал, если дествительно статья поонравилась, дабы была обратная связь с читателями.
ter
11.10.2011 в 10:58
я бы сделал (: но к внутренностям блога доступа не имею (:
хочу уже давно сделать отдельный сайт, но что-то все времени на это не хватает
- Имя
- e-mail*
- Сайт
вы можете использовать теги [i],[b],[code],[quote]
Дополнительно