리샤오핑/허베이성 구안시 화북석유공업대학
---- 어떤 프로그램을 개발하든 데이터 입력은 필수입니다. 아름다운 입력 인터페이스를 빠르게 생성하면 의심할 여지 없이 프로그램 개발 효율성이 크게 향상됩니다. 시스템의 원래 제어가 만족스럽지 못한 경우가 많습니다. Delphi에서는 특정 필드에 대한 경우 선택적 컨트롤은 DBLabel, DBEdit 등입니다. 전체 테이블의 입력에 대한 경우에는 DBGrid가 있습니다. Dbedit와 같은 컨트롤을 사용할 때 사용자는 각 필드의 위치를 완전히 정렬해야 합니다. 비록 아름다운 효과를 얻을 수 있지만 필드가 많으면 의심할 여지 없이 매우 번거로울 것입니다. DBGrid를 사용하면 필드가 아무리 많아도 하나의 컨트롤이면 충분하지만, 필드가 하나씩 배열되어 있어서 사용하기가 조금 불편합니다. 일반 사용자에게는 테이블 형식의 입력이 편리하고 아름답습니다. 이것이 이 글이 해결하고자 하는 문제이다.
----기술적 키
----이 컨트롤의 주요 기능은 데이터베이스 필드를 편집하는 것입니다. 일반 규칙에 따르면 컨트롤은 TdataLink 개체를 포함해야 하며 TdataLink와 관련된 일련의 메서드를 구현해야 하지만 이는 많은 코드를 소모합니다. 코드의 양이 많을수록 시스템이 더 복잡해지고 오류 가능성도 커집니다. 이 컨트롤의 개발 아이디어는 최소한의 코드로 최대한의 기능을 구현하는 것입니다. 따라서 TDBComboBox 컨트롤을 사용하여 데이터 필드를 직접 편집하십시오.
---- 보편성을 달성하기 위해 필드 편집 컨트롤 배열과 필드 제목 배열이 컨트롤 내부에 유지됩니다. 다음과 같이:
편집기: TDBComboBox 배열;
->동적으로 생성되고 편집에 사용되는 특정 데이터 컨트롤 배열
라벨: TLabel 배열;
->각 필드의 제목은 동적으로 생성됩니다.
----TDBComboBox를 사용하면 일반적인 편집 기능뿐만 아니라 각 필드에 해당 프롬프트 정보를 추가할 수도 있다는 장점이 있습니다. 코드는 다음과 같습니다:
{필드 I에 프롬프트 정보를 추가하는 방법}
절차 TDBPanel.AddHits
(ItemIndex: 정수; 조회수: 문자열 배열);
var
m,n,i: 정수;
시작하다
n := 길이(편집자);
m := 길이(조회수);
ItemIndex<n이면 시작합니다.
i:=0 ~ m-1의 경우 Editors[ItemIndex].Items.Add(Hits[i]);
끝;
끝;
---- 특정 응용 프로그램은 매우 다양하므로 프로그래머가 특정 응용 프로그램에 대한 특수 기능을 구현할 수 있도록 제어에는 충분한 이벤트 처리 인터페이스가 있어야 합니다. 이를 위해서는 사용자가 구현할 컨트롤에 특정 이벤트 처리 방법을 정의해야 합니다. 여기서 제공하는 것은 모든 필드를 편집할 때 수행되는 처리인 OnOkClick 이벤트입니다. 코드는 다음과 같습니다:
OkButton: T버튼;
-> 마지막으로 추가된 확인 버튼은 제출 작업을 구현하는 데 사용됩니다.
OnOkClick 속성: TNotifyEvent 읽기 FClick 쓰기 FClick;
---- OnOKClick 메서드를 구현하면 사용자는 제출, 데이터 합리성 테스트 등 다양한 처리 작업을 완료할 수 있습니다. 특별한 대우가 필요한 또 다른 것은 다양한 분야 간의 전환을 제어하는 것입니다. 기본값은 마우스로 클릭하는 것입니다. 그러나 사용자들의 습관은 키보드의 '위, 아래, 왼쪽, 오른쪽' 네 개의 화살표 키를 사용하는 경우가 많습니다. 이 기능을 구현하려면 다음 두 가지 메서드를 정의해야 합니다.
절차 AKeyPress(Sender: TObject; var Key: Char);
프로시저 AKeyDown(Sender: TObject;
var 키: 단어; Shift: TShiftState);
---- 위의 두 가지 메소드를 동적으로 생성된 편집기에 할당하여 화살표 키에 대한 응답을 구현합니다.
---- 테이블마다 필드 수가 다르므로 표시되지 않을 수 있으며 스크롤 기능이 필요합니다. 따라서 TscrollBox 컨트롤이 컨트롤에 삽입됩니다. 마지막으로 주목해야 할 점은 동적 컨트롤의 실행 취소와 메모리 해제입니다. 컨트롤 배열의 실행 취소 및 메모리 해제 순서는 생성 순서와 정반대입니다. 그렇지 않으면 뭔가 잘못될 것입니다.
----컨트롤 사용
---- 먼저 DBPanel 컨트롤을 폼에 배치한 다음 데이터 소스 속성, 데이터 입력 폼의 열 수 및 기타 속성을 설정합니다. 프로그램에서 데이터 소스를 연 후 메서드를 호출하여 데이터 편집 컨트롤을 생성하면 됩니다. 지금 바로:
Query1.Open;->데이터 소스 열기
DBPanel1.CreateEditors ->각 필드에 대한 편집 컨트롤 생성
DBPanel1.AddHits(0,['1111','11222','eeee']);
->특정 필드에 대한 프롬프트 정보 설정
DBPanel1.AddHits(1,['1111','11222','eeee']);
->특정 필드에 대한 프롬프트 정보 설정
제어 및 샘플 프로그램은 Win98+Delphi 5.0 환경에서 디버깅되었습니다.
---- 첨부: TDBPanel 소스코드
단위 DBPanel;
인터페이스
용도
Windows, 메시지, SysUtils, 클래스,
그래픽, 컨트롤, 양식, 대화 상자,
ExtCtrls, dbctrls, stdctrls, db;
유형
TDBPanel = 클래스(TPanel)
사적인
{비공개 선언}
FLft: 정수;
FTop: 정수;
maxTextLen: 정수;
maxLabelLen: 정수;
FScrollBox: TScrollBox;{스크롤 제어}
FLineHeight: 정수;
FClick: TNotifyEvent;
편집기: TDBComboBox 배열;
->동적으로 생성되고 편집에 사용되는 특정 데이터 컨트롤 배열
라벨: TLabel 배열;
->각 필드의 제목은 동적으로 생성됩니다.
OkButton: T버튼;
-> 마지막으로 추가된 확인 버튼은 제출 작업을 구현하는 데 사용됩니다.
{데이터 소스}
FDataSource: TDataSource;
F열: 정수;
->테이블의 열 수를 입력하세요.
보호됨
{ 보호된 선언 }
절차 FreeEditors;
-> 데이터 입력 제어 메모리 해제
공공의
절차 CreateEditors;//
(DS: TDataSource; ColCount: 정수);
->각 필드에 대한 데이터 입력 컨트롤 만들기
생성자 Create(AOwner:
TComponent);
소멸자 재정의;
절차 AKeyPress(발신자:
TObject; var 키: 문자);
프로시저 AKeyDown(발신자:
TObject; var 키: 단어:
TShiftState);
절차 ClearHits(ItemIndex: Integer);
프로시저 AddHits(ItemIndex:
정수; 문자열 배열);
함수 편집기(색인: 정수):
TDBComboBox;
{공개 선언}
출판됨
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:
정수; 문자열 배열);
var
m,n,i: 정수;
시작하다
n := 길이(편집자);
m := 길이(조회수);
ItemIndex<n이면 시작합니다.
i:=0 ~ m-1의 경우 Editors[ItemIndex].Items.Add(Hits[i]);
끝;
끝;
절차 TDBPanel.AKeyDown
(보내는 사람: TObject; var 키: Word;
시프트: TShiftState);
시작하다
if (발신자가 TDBComboBox) 다음 시작
케이스 키
VK_Next: (TDBComboBox로 보낸 사람)
.DataSource.DataSet.Next;
VK_PRIOR: (TDBComboBox로 보낸 사람)
.DataSource.DataSet.Prior;
끝;
끝;
끝;
절차 TDBPanel.AKeyPress(Sender: TObject; var Key: Char);
시작하다
if (발신자가 TDBComboBox) 다음 시작
if Key=#13 then (TForm 소유자).Perform(WM_NEXTDLGCTL, 0, 0);
끝;
끝;
절차 TDBPanel.ClearHits(ItemIndex: Integer);
var
n: 정수;
시작하다
n := 길이(편집자);
if ItemIndex< n then Editors[ItemIndex].Items.Clear;
끝;
생성자 TDBPanel.Create(AOwner: TComponent);
시작하다
상속된 생성(AOWner);
F왼쪽 :=10;
FTop := 10;
maxTextLen := 100;
maxLabelLen := 100;
FLineHeight := 15;
끝;
{필드별 데이터 입력 컨트롤 생성 방법}
절차 TDBPanel.CreateEditors;//
(DS: TDataSource; ColCount: 정수);
var
i, n, RowCount: 정수;
텍스트 높이: 정수;
시작하다
DataSource.DataSet.Active이면 시작됩니다.
n := DataSource.DataSet.FieldCount;
{최대 제목 길이 및 표시 길이 계산}
데이터소스.DataSet.First;
{키 계산}
TextHeight := Canvas.TextHeight(데이터소스
.DataSet.Fields[0].DisplayLabel) + FLineHeight;
{행과 열의 수 계산}
RowCount := n div 열;
n mod Columns < > 0이면 inc(RowCount);
{메모리 할당}
무료편집자;
SetLength(편집자, n);
SetLength(레이블, n);
{스크롤 상자 생성}
FScrollBox := TScrollBox.Create(소유자);
FScrollBox.Parent := 자체;
FScrollBox.Align := alClient;
{생성편집}
i:=0에서 n-1까지 시작하세요
{제목 만들기}
Labels[i] := TLabel.Create(Owner);
Labels[i].Parent := FScrollBox; //자기;
라벨[i].Caption := DataSource.DataSet.Fields[i].DisplayLabel;
라벨[i].Left := FLeft + (maxLabelLen +
maxTextLen + 10) * (i div RowCount);
라벨[i].Width := maxLabelLen;
Labels[i].Top := FTop + (i mod RowCount) * TextHeight + 5;
{편집 개체 생성}
Editors[i] := TDBComboBox.Create(Owner);
Editors[i].Parent := FScrollBox; //자체;
Editors[i].Left := Labels[i].Left + Labels[i].Width;
편집자[i].Width := maxTextLen;
Editors[i].Top := FTop + (i mod 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 := 편집자[n-1].Top + TextHeight;
OkButton.Caption := '확인';
OKButton.OnClick := FClick;
끝;
끝;
소멸자 TDBPanel.Destroy;
시작하다
무료편집자;
상속됨 파기;
끝;
함수 TDBPanel.Editor(색인: 정수): TDBComboBox;
시작하다
if Index< Length(Editors) then Result := 편집자[Index]
else 결과 := nil;
끝;
절차 TDBPanel.FreeEditors;
var
i,n: 정수;
시작하다
{메모리는 순서대로 해제되어야 합니다! 생성 순서의 역순으로 하셔야 합니다!
특히 구성요소 간에 상위-하위 관계가 있는 경우}
OkButton< >nil이면 OkButton.Free;
편집자< >nil이면 시작됩니다.
n := 길이(편집자);
i:=0 ~ n-1의 경우 Editors[i].free;
편집자 := 없음;
n := 길이(레이블);
i:=0에서 n-1까지 do Labels[i].Free;
라벨 := nil;
끝;
FScrollBox< >nil이면 시작됩니다.
FScrollBox.Free;
FScrollBox := nil;
끝;
끝;
끝.