2015-02-01 2 views
0

나는 편집을 위해 입력 된 정보로 데이터베이스 테이블을 업데이트해야하며, 버튼을 눌러 업데이트 할 필요가있는 프로그램이 있습니다. 그러나 런타임에 폼이 만들어지고 버튼을 비롯한 모든 요소가 같은 방식으로 만들어집니다.런타임에 델파이 버튼의 OnClick 프로 시저 설정하기

:처럼 작성 사전

procedure UpdateDatabase(Field1,Field2,Field3:string); 
begin 
//update database here... 
end; 

는 그 다음 매개 변수를 사용하여이 절차에 내 단추의 OnClick 이벤트를 할당 : I 데이터베이스 인수는 데이터베이스 등을 업데이트하는 절차를 정의하는 것입니다 수있는 방법을 생각

Button1.OnClick := UpdateDatabase(Edit1.text,Edit2.Text,Edit3.Text); 

그러나 형식에 다른 데이터 형식이 필요하므로 호환되지 않습니다. 나는 또한 매개 변수가 일반적으로 OnClick 함수로 전달 될 수 없다는 것을 알아 차렸다. 실제로 내가 제안한 것을 성취 할 수있는 방법이 있습니까?

이는 현재의 내 생성 버튼 코드가있다 :

function buttonCreate(onClickEvent: TProcedure; 
    left: integer; top: integer; width: integer; height: integer; 
    anchors: TAnchors; caption: string; parent: TWinControl; form: TForm;): TButton; 
var 
    theButton: TButton; 
begin 
    theButton := TButton.Create(form); 
    theButton.width := width; 
    theButton.height := height; 
    theButton.left := left; 
    theButton.top := top; 
    theButton.parent := parent; 
    theButton.anchors := anchors; 
    //theButton.OnClick := onClickEvent; 
    theButton.Caption := caption; 
    result := theButton; 
end; 

모든 모든 도움에 감사!

+0

예, 귀하의 절차는 이벤트 유형 (발송 인 : TObject)의 규칙을 준수해야합니다. 그런 다음 자신의 프로 시저를 그 안에 넣습니다. –

+0

예를 들려 줄 수 있습니까? 죄송합니다. 델파이에 조금 익숙합니다. –

+0

단추 컨트롤 이전 또는 이후에 편집 컨트롤이 만들어 졌습니까? –

답변

6

이벤트 핸들러는 이벤트 유형이 정의 된 방식으로 정확하게 선언되어야합니다. OnClick 이벤트는 TNotifyEvent으로 선언되며 매개 변수는 (Sender: TObject)입니다. 그 규칙을 깨뜨릴 수는 없습니다. 귀하의 경우에는

, 당신은 TNotifyEvent이 이벤트 핸들러가 있어야합니다 의미 "개체의"절차입니다

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    UpdateDatabase(Edit1.text,Edit2.Text,Edit3.Text); 
end; 

하는 것으로 ...과 같이, 이벤트 핸들러의 내부에 자신의 절차를 포장 할 수 있습니다 객체의 내부에서 선언됩니다. 귀하의 경우, 이벤트 처리기는 양식 내에 선언되어야합니다 (전역 위치가 아님).

+0

그러나이 시나리오에서 Edit1.text 등은 정의되지 않을 것입니다. 런타임에 해당 구성 요소가 만들어지기 때문입니다. 데이터를 전송할 방법이 있습니까? –

+0

이 이벤트 핸들러가 동일한 양식의 내부에 선언되어있는 한 사실이 아닙니다. 이제 코드를 좀 더 철저히 읽었으므로 자연스럽게 그것을 수행하는 방법이 아닌'form' 변수 (대부분 글로벌 일 가능성이 있음)를 참조하는 것으로 보입니다. 이 모든 것은 양식 안에 자체 포함되어야하며, 그것에 대해 걱정할 필요가 없습니다. –

+0

그러나 편집 할 때 Edit1이 작성되지 않았으므로 Edit1.Text에 대한 참조가 유효하지 않습니다. –

2

편집 컨트롤을 필드 멤버로 사용하여 TButton에서 컨트롤을 내림차순으로 생각한 적이 있습니까?

다음은 아이디어를 수집 할 수있는 예입니다.

TButtonHack = class(TButton) 
    fEdit1, 
    fEdit2, 
    fEdit3: TEdit; 
    procedure Click; override; 
    public 
    constructor Create(AOwner: TComponent; AParent: TWinControl; Edit1, Edit2, Edit3: TEdit); Reintroduce; 
end; 

Constructor TButtonHack.Create(AOwner: TComponent; AParent: TWinControl; Edit1, Edit2, Edit3: TEdit); 
begin 
    inherited Create(AOwner); 
    Parent := AParent; 
    Left := 100; 
    Top := 100; 
    Width := 100; 
    Height := 20; 
    Caption := 'ButtonHack'; 
    fEdit1 := Edit1; 
    fEdit2 := Edit2; 
    fEdit3 := Edit3; 
end; 

procedure TButtonHack.Click; 
begin 
    Inherited Click; 
    Showmessage(fEdit1.text+','+ fEdit2.text+','+fEdit3.text); 
end; 

테스트하려면 폼에 3 개의 TEdit을 테스트하십시오.

procedure TForm1.Button1Click(Sender: TObject); 
var 
    ButtonHack: TButtonHack; 
begin 
    ButtonHack := TButtonHack.Create(Form1, Form1, Edit1, Edit2, Edit3); 
end; 

편집 내용을 미리 작성할지 또는 TButtonHack 내에서 편집할지 여부는 귀하에게 달려 있습니다. 가능한 한 간단하게 예제를 단순화했습니다.

+2

상속은 좋지 않은 선택입니다. 일반적으로 상속을 피해야합니다. 당신은 단순히 그것을 필요로하지 않습니다. 편집을 볼 수 있으려면 OnClick 핸들러 만 있으면됩니다. 물론 생성자에서 부모와 위치를 설정하는 것은 매우 나쁜 냄새입니다. 더 평범한 메모에서, 나는'var '이 그 맥락에서 무엇을 의미하는지 완전히 이해하지 못한다고 생각한다. –

+0

나는이 객체가 참조에 의해 전달되었다는 것을 안다. var를이 예제에서 의도를 진술하는 수단으로 사용했다. 편집 및 제거되었습니다. –

+0

개체는 "참조로 전달"되지 않습니다. 무슨 뜻인지는 알지만 사용하는 용어는 부정확합니다. 'TObject'에서 파생 된 타입의 변수는 ** 참조 **입니다. 포인터의 멋진 이름입니다. 참조를 전달하면 (예 : 'Sender : TObject' 당신은 값으로 참조를 전달합니다. 즉, 객체의 주소를 보유하고있는 포인터의 값을 전달합니다. –

관련 문제