Ли Сяопин/Северо-Китайский университет нефтяников в Гуане, провинция Хэбэй
---- Какая бы программа ни разрабатывалась, ввод данных необходим. Быстрое создание красивого интерфейса ввода, несомненно, значительно повысит эффективность разработки программ. Первоначальные элементы управления системой часто неудовлетворительны. В Delphi, если это для определенного поля, необязательными элементами управления являются DBLabel, DBEdit и т. д., если для ввода всей таблицы, есть DBGrid. При использовании элементов управления, таких как Dbedit, пользователи должны полностью упорядочить позиции каждого поля. Хотя можно добиться красивых эффектов, несомненно, будет очень хлопотно, если полей будет много. Если используется DBGrid, сколько бы полей ни было, достаточно одного элемента управления. Это просто, но поля располагаются одно за другим, что немного неудобно в использовании. Для обычных пользователей ввод в виде таблицы — это и удобно, и красиво. Именно эту проблему призвана решить данная статья.
----Технический ключ
----Основной функцией этого элемента управления является редактирование полей базы данных. По общим правилам элемент управления должен содержать объект TdataLink и реализовывать ряд методов, связанных с TdataLink, однако для этого потребуется много кода; Чем больше объем кода, тем сложнее система и тем больше вероятность ошибок. Идея разработки этого элемента управления заключается в достижении максимального количества функций с наименьшим количеством кода. Поэтому редактируйте поля данных напрямую с помощью элемента управления TDBComboBox.
---- Для достижения универсальности внутри элемента управления поддерживаются массив элементов управления редактированием полей и массив заголовков полей. следующее:
Редакторы: массив TDBComboBox;
-> Определенный массив элементов управления данными, используемый для редактирования, динамически генерируемый.
Метки: массив TLabel;
-> Заголовок каждого поля генерируется динамически.
----Преимущество использования TDBComboBox заключается в том, что он не только имеет общие функции редактирования, но также может добавлять соответствующую подсказку к каждому полю. Код выглядит следующим образом:
{Метод добавления оперативной информации в поле I}
ПРОЦЕДУРА TDBPanel.AddHits
(ItemIndex: целое число; попадания: массив строк);
вар
m,n,i: целое число;
начинать
n := Длина(Редакторы);
м := Длина(Хит);
если ItemIndex< n, то начать
для i:=0 до m-1 do Editors[ItemIndex].Items.Add(Hits[i]);
конец;
конец;
---- Конкретные приложения сильно различаются, поэтому элементу управления также необходимо оставить достаточное количество интерфейсов обработки событий, чтобы программисты могли реализовать специальные функции для конкретных приложений. Это требует определения определенных методов обработки событий в элементе управления, которые пользователи смогут реализовать. Здесь представлено событие OnOkClick, которое представляет собой обработку, выполняемую при редактировании всех полей. Код выглядит следующим образом:
ОкКнопка: TButton;
-> Последняя добавленная кнопка «ОК» используется для реализации действия отправки.
свойство OnOkClick: TNotifyEvent чтение FClick запись FClick;
---- Реализуя метод OnOKClick, пользователи могут выполнять различные задачи обработки, такие как отправка и проверка рациональности данных. Еще одна вещь, требующая особого подхода, — это управление преобразованием между различными полями. По умолчанию используется щелчок мышью. Однако пользователи часто используют четыре клавиши со стрелками «вверх, вниз, влево и вправо» на клавиатуре. Для реализации этой функции необходимо определить следующие два метода:
процедура AKeyPress (Отправитель: TObject; var Key: Char);
процедура AKeyDown (Отправитель: TObject;
ключ вар: слово; сдвиг: TShiftState);
---- Назначьте два вышеуказанных метода динамически создаваемым редакторам, чтобы добиться реакции на клавиши со стрелками.
---- Разные таблицы имеют разное количество полей и могут не отображаться, поэтому требуется функция прокрутки. Итак, в элемент управления вставляется элемент управления TscrollBox. Последнее, на что следует обратить внимание, — это отмена динамического управления и освобождение памяти. Отмена управляющего массива и освобождение памяти выполняются в порядке, прямо противоположном созданию. Иначе что-то пойдет не так.
----Использование элементов управления
---- Сначала поместите элемент управления DBPanel в форму, а затем задайте свойства источника данных, количество столбцов формы ввода данных и другие свойства. В программе после открытия источника данных достаточно вызвать метод создания элемента управления редактированием данных. Прямо сейчас:
Query1.Open;->Открыть источник данных
DBPanel1.CreateEditors -> Создать элементы управления редактированием для каждого поля.
DBPanel1.AddHits(0,['1111','11222','eeee']);
-> Установить подсказку для определенного поля
DBPanel1.AddHits(1,['1111','11222','eeee']);
-> Установить подсказку для определенного поля
Контрольная и примерная программы отлажены в среде Win98+Delphi 5.0.
---- Вложение: Исходный код TDBPanel.
модуль ДБпанель;
интерфейс
использует
Windows, сообщения, SysUtils, классы,
Графика, элементы управления, формы, диалоги,
ExtCtrls, dbctrls, stdctrls, БД;
тип
TDBPanel = класс (TPanel)
частный
{Частные заявления}
Fслева: целое число;
ФТоп: целое число;
макстекстлен: целое число;
МаксЛабельЛен: Целое число;
FScrollBox: TScrollBox;{управление прокруткой}
FLineHeight: целое число;
FClick: TNotifyEvent;
Редакторы: массив TDBComboBox;
-> Определенный массив элементов управления данными, используемый для редактирования, динамически генерируемый.
Метки: массив TLabel;
-> Заголовок каждого поля генерируется динамически.
ОкКнопка: TButton;
-> Последняя добавленная кнопка «ОК» используется для реализации действия отправки.
{источник данных}
ФДатасаурце: Тдатасаурце;
FColumns: целое число;
->Введите количество столбцов таблицы
защищенный
{ Защищенные объявления }
процедура FreeEditors;
-> Освободить память управления вводом данных
общественный
процедура CreateEditors;//
(DS: TDataSource; ColCount: Integer);
-> Создать элементы управления вводом данных для каждого поля
конструктор Create(AOwner:
Ткомпонент); переопределить;
деструктор Уничтожить;
процедура AKeyPress(Отправитель:
TObject; ключ вар: Char);
процедура AKeyDown(Отправитель:
TObject; вар Ключ: Слово;
Тшифтстате);
процедура ClearHits (ItemIndex: Integer);
процедура AddHits(ItemIndex:
Целое число; Хиты: массив строк);
Редактор функций (индекс: целое число):
ТДБКомбоБокс;
{Публичные заявления}
опубликовано
propertyLeftLimit: чтение целого числа
FLeft запись FLeft по умолчанию 10;
свойство TopLimit: чтение целых чисел
FTop запись FTop по умолчанию 10;
свойство EditorLen: чтение целых чисел
maxTextLen написать maxTextLen;
свойство LabelLen: чтение целого числа
maxLabelLen записать maxLabelLen по умолчанию 100;
свойство LineHeight: чтение целого числа
FLineHeight запись FLineHeight по умолчанию 15;
свойство OnOkClick: TNotifyEvent
прочитать FClick записать FClick;
Источник данных свойства: TDataSource
прочитать FDataSource записать FDataSource;
-> Источник данных
Столбцы свойств: Целочисленное чтение
FColumns записывает FColumns;->Количество столбцов таблицы
{ Опубликованные декларации }
конец;
процедура Регистр;
выполнение
процедура Регистр;
начинать
RegisterComponents('Дополнительно', [TDBPanel]);
конец;
{Метод добавления оперативной информации в поле I}
процедура TDBPanel.AddHits(ItemIndex:
Целое число; Хиты: массив строк);
вар
m,n,i: целое число;
начинать
n := Длина(Редакторы);
м := Длина(Хит);
если ItemIndex< n, то начать
для i:=0 до m-1 do Editors[ItemIndex].Items.Add(Hits[i]);
конец;
конец;
процедура TDBPanel.AKeyDown
(Отправитель: TObject; Ключ var: Word;
Сдвиг: TShiftState);
начинать
если (Отправитель — TDBComboBox), то начните
чехол Ключ
VK_Next: (Отправитель как TDBComboBox)
.DataSource.DataSet.Next;
VK_PRIOR: (Отправитель как TDBComboBox)
.DataSource.DataSet.Prior;
конец;
конец;
конец;
процедура TDBPanel.AKeyPress(Sender: TObject; var Key: Char);
начинать
если (Отправитель — TDBComboBox), то начните
если Key=#13, то (Владелец как TForm).Perform(WM_NEXTDLGCTL, 0, 0);
конец;
конец;
процедура TDBPanel.ClearHits(ItemIndex: Integer);
вар
n: целое число;
начинать
n := Длина(Редакторы);
если ItemIndex< n, то Editors[ItemIndex].Items.Clear;
конец;
конструктор TDBPanel.Create(AOwner: TComponent);
начинать
Унаследованное создание (AOOWNer);
FСлева :=10;
ФТоп := 10;
МаксТекстЛен: = 100;
МаксЛабельЛен: = 100;
ФЛинеХайт: = 15;
конец;
{Метод создания элементов управления вводом данных для каждого поля}
процедура TDBPanel.CreateEditors;//
(DS: TDataSource; ColCount: Integer);
вар
я, п, RowCount: целое число;
TextHeight: целое число;
начинать
если DataSource.DataSet.Active, то начните
n := DataSource.DataSet.FieldCount;
{Рассчитать максимальную длину заголовка и длину отображения}
DataSource.DataSet.First;
{рассчитать высоту}
TextHeight := Canvas.TextHeight(DataSource
.DataSet.Fields[0].DisplayLabel) + FLineHeight //10;
{Посчитать количество строк и столбцов}
RowCount: = n столбцов div;
если n mod Columns < > 0, то inc(RowCount);
{Выделить память}
Бесплатные редакторы;
SetLength (Редакторы, n);
SetLength (Ярлыки, n);
{Создать поле прокрутки}
FScrollBox: = TScrollBox.Create(Владелец);
FScrollBox.Parent := Self;
FScrollBox.Align := alClient;
{СоздатьРедактировать}
для i:=0 до n-1 начать
{Создать заголовок}
Ярлыки[i] := TLabel.Create(Владелец);
Метки[i].Parent := FScrollBox; //Self;
Метки[i].Caption := DataSource.DataSet.Fields[i].DisplayLabel;
Labels[i].Left := FLeft + (maxLabelLen +
maxTextLen + 10) * (я div RowCount);
Labels[i].Width := maxLabelLen;
Labels[i].Top := FTop + (i mod RowCount) * TextHeight + 5;
{Создать объект редактирования}
Редакторы[i] := TDBComboBox.Create(Владелец);
Редакторы[i].Parent := FScrollBox; //Self;
Редакторы[i].Left := Labels[i].Left + Labels[i].Width;
Редакторы[i].Width := maxTextLen;
Editors[i].Top := FTop + (я мод RowCount) * TextHeight;
Редакторы[i].DataSource := DataSource;
Редакторы[i].DataField := DataSource.DataSet.Fields[i].FieldName;
Редакторы[i].OnKeyPress := AKeyPress;
Редакторы[i].OnKeyDown := AKeyDown;
конец;
{Кнопка "Создать ОК"}
OkButton := TButton.Create(Владелец);
OkButton.Parent := FScrollBox;
OkButton.Left := Редакторы[n-1].Left;
OkButton.Top := Editors[n-1].Top + TextHeight;
OkButton.Caption := 'ОК';
OKButton.OnClick := FClick;
конец;
конец;
деструктор TDBPanel.Destroy;
начинать
Бесплатные редакторы;
Унаследованное уничтожение;
конец;
функция TDBPanel.Editor(Индекс: Целое число): TDBComboBox;
начинать
если Индекс < Длина (Редакторы), то Результат: = Редакторы [Индекс]
еще Результат:= ноль;
конец;
процедура TDBPanel.FreeEditors;
вар
я, п: целое число;
начинать
{Память должна быть освобождена по порядку! Должно быть сделано в порядке, обратном созданию!
Особенно, когда между компонентами существует связь родитель-потомок}
если OkButton< >nil, то OkButton.Free;
если Editors< >nil, то начнем
n := Длина(Редакторы);
для i:=0 до n-1 do Editors[i].free;
Редакторы := ноль;
n := Длина(Ярлыки);
для i:=0 до n-1 do Labels[i].Free;
Метки := ноль;
конец;
если FScrollBox< >nil, то начать
FScrollBox.Бесплатно;
FScrollBox: = ноль;
конец;
конец;
конец.