Li Xiaoping/Universidad de Trabajadores del Petróleo del Norte de China en Gu'an, provincia de Hebei
---- No importa qué tipo de programa se desarrolle, la entrada de datos es indispensable. Sin duda, generar rápidamente una hermosa interfaz de entrada mejorará en gran medida la eficiencia del desarrollo del programa. Los controles originales del sistema suelen ser insatisfactorios. En Delphi, si es para un campo determinado, los controles opcionales son DBLabel, DBEdit, etc.; si es para el ingreso de toda la tabla, está DBGrid. Al utilizar controles como Dbedit, los usuarios deben organizar completamente las posiciones de cada campo. Aunque puede lograr efectos hermosos, sin duda será muy problemático si hay muchos campos. Si se usa DBGrid, no importa cuántos campos haya, solo un control es suficiente. Es simple, pero los campos están organizados uno por uno, lo cual es un poco incómodo de usar. Para los usuarios comunes, la entrada en forma de tabla es conveniente y hermosa. Éste es el problema que este artículo pretende resolver.
----Clave técnica
----La función principal de este control es editar campos de la base de datos. Según las reglas generales, el control debe contener un objeto TdataLink e implementar una serie de métodos relacionados con TdataLink; sin embargo, eso consumirá mucho código; Cuanto mayor sea la cantidad de código, más complejo será el sistema y mayor será la posibilidad de errores. La idea de desarrollo de este control es lograr la mayor cantidad de funciones con la menor cantidad de código. Por lo tanto, edite los campos de datos directamente usando el control TDBComboBox.
---- Para lograr la universalidad, dentro del control se mantienen una matriz de control de edición de campos y una matriz de título de campo. como sigue:
Editores: matriz de TDBComboBox;
->Una matriz específica de controles de datos utilizados para la edición, generados dinámicamente
Etiquetas: matriz de TLabel;
->El título de cada campo se genera dinámicamente
---- La ventaja de usar TDBComboBox es que no solo tiene funciones de edición generales, sino que también puede agregar la información de solicitud correspondiente a cada campo. El código es el siguiente:
{Método para agregar información solicitada al campo I}
Procedimiento TDBPanel.AddHits
(ItemIndex: entero; Hits: matriz de cadena);
var
m,n,i: Entero;
comenzar
n := Longitud(Editores);
m := Longitud(Golpes);
si ItemIndex < n entonces comienza
para i:=0 a m-1 haga Editors[ItemIndex].Items.Add(Hits[i]);
fin;
fin;
---- Las aplicaciones específicas varían ampliamente, por lo que el control también debe dejar suficientes interfaces de procesamiento de eventos para que los programadores implementen funciones especiales para aplicaciones específicas. Esto requiere definir ciertos métodos de procesamiento de eventos en el control para que los usuarios los implementen. Lo que se proporciona aquí es un evento OnOkClick, que es el procesamiento que se realiza cuando se editan todos los campos. El código es el siguiente:
Botón Ok: Botón T;
->El último botón Aceptar agregado se utiliza para implementar la acción de envío.
propiedad OnOkClick: TNotifyEvent leer FClick escribir FClick;
---- Al implementar el método OnOKClick, los usuarios pueden completar diversas tareas de procesamiento, como el envío y las pruebas de racionalidad de los datos. Otra cosa que requiere un tratamiento especial es el control de la conversión entre varios campos. Lo predeterminado es hacer clic con el mouse. Sin embargo, el hábito de los usuarios suele ser utilizar las cuatro teclas de flecha "arriba, abajo, izquierda y derecha" del teclado. Para implementar esta función, es necesario definir los dos métodos siguientes:
procedimiento AKeyPress(Remitente: TObject; var Clave: Char);
procedimiento AKeyDown(Remitente: TObject;
var Clave: Palabra Shift: TShiftState);
---- Asigne los dos métodos anteriores a editores generados dinámicamente para implementar la respuesta a las teclas de flecha.
---- Diferentes tablas tienen diferentes números de campos, que pueden no mostrarse, lo que requiere una función de desplazamiento. Entonces, se inserta un control TscrollBox en el control. Lo último a tener en cuenta es la deshacer los controles dinámicos y la liberación de memoria. La deshacer la matriz de control y la liberación de la memoria están en orden: exactamente el orden opuesto de la creación. De lo contrario, algo saldrá mal.
----Uso de controles
---- Primero coloque el control DBPanel en el formulario y luego configure las propiedades de la fuente de datos, el número de columnas del formulario de entrada de datos y otras propiedades. En el programa, después de abrir la fuente de datos, simplemente llame al método para crear el control de edición de datos. Ahora mismo:
Consulta1.Abrir;->Abrir fuente de datos
DBPanel1.CreateEditors ->Crear controles de edición para cada campo
DBPanel1.AddHits(0,['1111','11222','eeee']);
->Establecer información de solicitud para un campo determinado
DBPanel1.AddHits(1,['1111','11222','eeee']);
->Establecer información de solicitud para un campo determinado
El programa de control y de muestra se ha depurado en el entorno Win98+Delphi 5.0.
---- Adjunto: Código fuente de TDBPanel
unidad DBPanel;
interfaz
usos
Windows, Mensajes, SysUtils, Clases,
Gráficos, controles, formularios, cuadros de diálogo,
ExtCtrls, dbctrls, stdctrls, db;
tipo
PanelTDB = clase(PanelTP)
privado
{Declaraciones privadas}
FLIzquierda: Entero;
FTop: Entero;
maxTextLen: entero;
maxLabelLen: entero;
FScrollBox: TScrollBox;{control de desplazamiento}
FLineHeight: entero;
FClick: TNotifyEvent;
Editores: matriz de TDBComboBox;
->Una matriz específica de controles de datos utilizados para la edición, generados dinámicamente
Etiquetas: matriz de TLabel;
->El título de cada campo se genera dinámicamente
Botón Ok: Botón T;
->El último botón Aceptar agregado se utiliza para implementar la acción de envío.
{fuente de datos}
FDataSource: TDataSource;
FColumnas: Entero;
->Ingrese el número de columnas de la tabla
protegido
{ Declaraciones protegidas }
procedimiento FreeEditores;
->Liberar memoria del control de entrada de datos
público
procedimiento CrearEditores;//
(DS: TDataSource; ColCount: entero);
->Crear controles de entrada de datos para cada campo
constructor Crear(APropietario:
TComponente); anulación;
destructor Destruir; anular;
procedimiento AKeyPress(Remitente:
TObject; var Clave: Char);
procedimiento AKeyDown(Remitente:
TObject; var Clave: Palabra;
TShiftState);
procedimiento ClearHits(ItemIndex: Integer);
procedimiento AddHits(ItemIndex:
Entero; Visitas: matriz de cadena);
Editor de funciones (Índice: Entero):
TDBComboBox;
{Declaraciones públicas}
publicado
propertyLeftLimit: lectura de enteros
FLeft escribe FLeft predeterminado 10;
propiedad TopLimit: lectura de enteros
FTop escribe FTop por defecto 10;
propiedad EditorLen: lectura entera
maxTextLen escribe maxTextLen;
propiedad LabelLen: lectura entera
maxLabelLen escribe maxLabelLen por defecto 100;
propiedad LineHeight: lectura entera
FLineHeight escribe FLineHeight por defecto 15;
propiedad OnOkClick: TNotifyEvent
leer FClick escribir FClick;
propiedad Fuente de datos: TDataSource
leer FDataSource escribir FDataSource;
->Fuente de datos
Columnas de propiedad: lectura entera
FColumns escribe FColumns;->número de columnas de la tabla
{ Declaraciones publicadas }
fin;
Registro de trámites;
implementación
Registro de trámites;
comenzar
RegisterComponents('Adicional', [TDBPanel]);
fin;
{Método para agregar información solicitada al campo I}
procedimiento TDBPanel.AddHits(ItemIndex:
Entero; Visitas: matriz de cadena);
var
m,n,i: Entero;
comenzar
n := Longitud(Editores);
m := Longitud(Golpes);
si ItemIndex < n entonces comienza
para i:=0 a m-1 haga Editors[ItemIndex].Items.Add(Hits[i]);
fin;
fin;
procedimiento TDBPanel.AKeyDown
(Remitente: TObject; var Clave: Palabra;
Cambio: TShiftState);
comenzar
si (el remitente es TDBComboBox), entonces comience
caso Clave de
VK_Next: (Remitente como TDBComboBox)
.DataSource.DataSet.Siguiente;
VK_PRIOR: (Remitente como TDBComboBox)
.DataSource.DataSet.Prior;
fin;
fin;
fin;
procedimiento TDBPanel.AKeyPress(Remitente: TObject; var Clave: Char);
comenzar
si (el remitente es TDBComboBox), entonces comience
si Clave=#13 entonces (Propietario como TForm).Perform(WM_NEXTDLGCTL, 0, 0);
fin;
fin;
procedimiento TDBPanel.ClearHits(ItemIndex: Integer);
var
n: número entero;
comenzar
n := Longitud(Editores);
si ItemIndex< n entonces Editors[ItemIndex].Items.Clear;
fin;
constructor TDBPanel.Create(AOwner: TComponent);
comenzar
Crear heredado (AOWNer);
FL izquierda :=10;
FArriba := 10;
maxTextLen := 100;
maxLabelLen := 100;
Altura de línea := 15;
fin;
{Método para crear controles de entrada de datos para cada campo}
procedimiento TDBPanel.CreateEditors;//
(DS: TDataSource; ColCount: entero);
var
i, n, RowCount: entero;
Altura del texto: entero;
comenzar
si DataSource.DataSet.Active entonces comienza
norte := DataSource.DataSet.FieldCount;
{Calcule la longitud máxima del título y la longitud de visualización}
Fuente de datos.DataSet.First;
{calcular altura}
Altura del texto := Canvas.TextHeight (Fuente de datos
.DataSet.Fields[0].DisplayLabel) + FLineHeight //10;
{Calcular el número de filas y columnas}
RowCount: = n columnas div;
si n mod Columnas < > 0 entonces inc(RowCount);
{Asignar memoria}
Editores gratuitos;
SetLength(Editores, n);
EstablecerLongitud(Etiquetas, n);
{Crear cuadro de desplazamiento}
FScrollBox := TScrollBox.Create(Propietario);
FScrollBox.Parent: = Yo;
FScrollBox.Align := alClient;
{CrearEditar}
para i:=0 a n-1 comenzar
{Crear título}
Etiquetas[i] := TLabel.Create(Propietario);
Etiquetas[i].Parent := FScrollBox; //Self;
Etiquetas[i].Caption := DataSource.DataSet.Fields[i].DisplayLabel;
Etiquetas[i].Izquierda := FLIzquierda + (maxLabelLen +
maxTextLen + 10) * (i div RowCount);
Etiquetas[i].Ancho := maxLabelLen;
Etiquetas[i].Top := FTop + (i mod RowCount) * TextHeight + 5;
{Crear objeto de edición}
Editores[i] := TDBComboBox.Create(Propietario);
Editores[i].Parent := FScrollBox; //Self;
Editores[i].Izquierda := Etiquetas[i].Izquierda + Etiquetas[i].Ancho;
Editores[i].Ancho := maxTextLen;
Editores[i].Top := FTop + (i mod RowCount) * TextHeight;
Editores[i].DataSource := DataSource;
Editores[i].DataField := DataSource.DataSet.Fields[i].FieldName;
Editores[i].OnKeyPress := AKeyPress;
Editores[i].OnKeyDown := AKeyDown;
fin;
{Crear botón Aceptar}
OkButton := TButton.Create(Propietario);
OkButton.Parent := FScrollBox;
OkButton.Left := Editores[n-1].Izquierda;
OkButton.Top := Editores[n-1].Top + TextHeight;
OkButton.Caption: = 'Aceptar';
OKButton.OnClick := FClick;
fin;
fin;
destructor TDBPanel.Destroy;
comenzar
Editores gratuitos;
Destrucción heredada;
fin;
función TDBPanel.Editor(Índice: Entero): TDBComboBox;
comenzar
si Índice <Longitud (Editores) entonces Resultado: = Editores [Índice]
de lo contrario Resultado: = nulo;
fin;
procedimiento TDBPanel.FreeEditors;
var
i,n: Entero;
comenzar
{¡La memoria debe liberarse en orden! ¡Debe hacerse en orden inverso al de creación!
Especialmente cuando existe una relación padre-hijo entre componentes}
si OkButton< >nil entonces OkButton.Free;
si los editores < > son nulos, entonces comience
n := Longitud(Editores);
para i:=0 a n-1 haga Editors[i].free;
Editores: = nulo;
n := Longitud(Etiquetas);
para i:=0 a n-1 haga Labels[i].Free;
Etiquetas: = nulo;
fin;
si FScrollBox< >nil entonces comienza
FScrollBox.Gratis;
FScrollBox: = nulo;
fin;
fin;
fin.