![]() |
Frame kann Objekte des Formulars nicht ändern
Hallo Zusammen,
so langsam werde ich wirklich wahnsinnig...:firejump: Ich habe auf meinem Hauptfomular ein Frame mit einer Tabelle. Wenn jetzt ein neuer Datensatz in der Tabelle angeklickt wird, wird ein Objekt mit Daten aus der Datenbank befüllt. Das klappt auch. Jetzt möchte ich aber, dass diese Daten in Labels auf dem Hauptformular angezeigt werden. Das wird eine Procedure auf dem Hauptformular aufgerufen, welche die Daten aus dem Objekt holt und in die Labels schreibt. Die ist auch in Ordnung, denn wenn ich sie von einem Button auf dem Hauptformular aus ausführe ändert sie die Labels - wie gewünscht. Da aber das auslösende Event das Selektieren eines neuen Datsatzes in der Tabelle auf dem Frame ist, möchte ich die Procedure von dort ausführen. Und das klappt nicht. Ich habe die Procedure publi gemacht, das Hauptformular in die uses aufgenommen. Die procedure wird auch gefunden und ausgeführt. Beim debuggen wird der Wert des Labels auch geändert, aber er wird nicht angezeigt. Auch Refresh & RePaint haben nichts gebracht. Dann habe ich versicht irgendein Label einfach mal vom Frame aus zu überschreiben - geht auch nicht... So langsam gehe ich unter die Decke. Bin ich so blöd oder mag mich mein Delphi nicht mehr??? Vielen Dank Patrick
Delphi-Quellcode:
unit Frame_UebersichtUnit;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, AdvObj, BaseGrid, AdvGrid, Vcl.ExtCtrls, AdvGlowButton, Vcl.StdCtrls, AdvEdit, DBAdvEd, TGridDesignUnit, TAuftragUnit, Frame_DetailsUnit; type TFrame_Uebersicht = class(TFrame) Grid_Uebersicht: TAdvStringGrid; Panel_Titel: TPanel; Glow_Aktualisieren: TAdvGlowButton; Edit_Schnellsuche: TDBAdvEdit; procedure FrameResize(Sender: TObject); procedure Grid_UebersichtGetAlignment(Sender: TObject; ARow, ACol: Integer; var HAlign: TAlignment; var VAlign: TVAlignment); procedure Grid_UebersichtGetFloatFormat(Sender: TObject; ACol, ARow: Integer; var IsFloat: Boolean; var FloatFormat: string); procedure Grid_UebersichtGetCellColor(Sender: TObject; ARow, ACol: Integer; AState: TGridDrawState; ABrush: TBrush; AFont: TFont); procedure Grid_UebersichtClick(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; implementation {$R *.dfm} uses MainUnit; //Das ist das Hauptfenster procedure TFrame_Uebersicht.Grid_UebersichtClick(Sender: TObject); begin Auftrag.Get_Auftrag(Grid_Uebersicht.Cells[1,Grid_Uebersicht.Row], Grid_Uebersicht.Cells[3,Grid_Uebersicht.Row]); //Das klappt Main.Details_exec; //Das Klappt nicht... end; Procedure Detailsexec
Delphi-Quellcode:
procedure TMain.Details_exec;
begin Clear_Details; Label_ArtikelNr.Caption:= Artikel.Artikel_Nr; Label_Bezeichnung1.Caption:= Artikel.Bezeichnung1; Try Label_Gewicht.Caption:= FloatToStr(Artikel.Gewicht); Except Label_Gewicht.Caption:='-'; End; Try Label_Sicherheitsbestand.Caption:=IntToStr(Artikel.Sicherheitsbestand); Except Label_Sicherheitsbestand.Caption:='-'; End; Label_AuftragNr.Caption:=Auftrag.Auftrag_Nr; Try Label_Menge.Caption:=IntToStr(Auftrag.Auftrag_Menge); Finally Label_Menge.Caption:='-'; End; Try Label_AuftragStatus.Caption:=IntToStr(Auftrag.Auftrag_Status); Except Label_AuftragStatus.Caption:='-'; End; if Auftrag.EilFa then Label_EilFA.Caption:='Ja' else Label_EilFA.Caption:='Nein'; Try Label_KritAT.Caption:=FloatToStr(Auftrag.KritAT); Except Label_KritAT.Caption:='-'; End; Label_Lagerzugang.Caption:=DateToStr(Auftrag.Lagerzugang); Try Label_AGStatus.Caption:=IntToStr(Arbeitsgang.AG_Status); Finally Label_AGStatus.Caption:='-'; End; Label_RMDatum.Caption:=DateToStr(Arbeitsgang.RM_Datum); Try Label_RMMenge.Caption:=IntToStr(Arbeitsgang.RM_Menge); Except Label_RMMenge.Caption:='-'; End; Try Label_AGNr.Caption:=IntToStr(Arbeitsgang.AG_Nr); Except Label_AGNr.Caption:='-'; End; Label_AGBezeichnung.Caption:=Arbeitsgang.AG_Bezeichnung; Label_Maschine.Caption:=Arbeitsgang.Maschine_Bezeichnung; Label_MaschineNr.Caption:=Arbeitsgang.Maschine_Nr; Label_Bezeichnung2.Caption:= Artikel.Bezeichnung2; end; |
AW: Frame kann Objekte des Formulars nicht ändern
Ich würde andersherum vorgehen: der Frame bekommt ein Event samt zugehöriger Property spendiert (OnDataClicked oder sowas). Das Formular kennt den Frame, kann also diesem Event einen Handler zuweisen. Wenn also das Ereignis im Frame auftritt, ruft dieser einfach nur den Handler (sofern zugewiesen) auf. Somit muss auch der Frame nix vom Formular wissen.
|
AW: Frame kann Objekte des Formulars nicht ändern
Hallo DeddyH,
das würde mir eh gut gefallen, dass ich das Hauptfenster garnicht in mein Frame mit einbinden muss. Aber leider habe ich keine Ahnung, wie ich das anstellen muss. Habe mir schon oft den Kopf zermatert, aber irgendwie scheine ich da ein große KnowHow-Lücke zu haben... Kannst Du mir da helfen? Wie gebe ich dem Frame (vom Hauptfenster aus?) ein Event, wenn auf dem Frame aggiert wird? Was ist ein Handler? Gruß Patrick |
AW: Frame kann Objekte des Formulars nicht ändern
Zitat:
Das kommt in den Frame
Delphi-Quellcode:
type
TDeinEvent = procedure(Sender: TObject; ...) of object;
Delphi-Quellcode:
private
FOnDataChanged: TDeinEvent; // Wenn dir der Sender ausreicht, dann einfach das fertige TNotifyEvent verwenden procedure DoDataChanged; published property OnDataChanged: TDeinEvent read FOnDataChanged write FOnDataChanged; Dann nur noch (das natürlich an passender Stelle aufrufen)
Delphi-Quellcode:
und in der Form dem Property deine Event-Methode zuweisen.
procedure TDeinFrame.DoDataChanged;
begin if Assigned(FOnDataChanged) then FOnDataChanged(Self); // siehe TDeinEvent ... man kann da gern auch noch irgendwelche weitere Parameter mitgeben end; |
AW: Frame kann Objekte des Formulars nicht ändern
Delphi-Quellcode:
wat :roteyes:
Try
Label_Menge.Caption:=IntToStr(Auftrag.Auftrag_Menge); Finally Label_Menge.Caption:='-'; End; PS: Leider kann man den Frame nicht mit zusätzlichen Properties und Events erweitern, so dass es direkt auf dem Formulardesigner angezeigt wird, so wie auch das OnClick-Event eines normalen TButtons. Man kann es so nur im Code machen :-( |
AW: Frame kann Objekte des Formulars nicht ändern
Event-Handler benutzt Du mit Sicherheit schon (unbewusst), seit Du mit Delphi begonnen hast. Das sind so Dinger wie TButton.OnClick oder TForm.OnCreate. So etwas ist recht einfach zu implementieren, wenn man einmal begriffen hat, wie man das macht. Mal ein Beispiel:
Delphi-Quellcode:
Im Hauptformular schreibst Du Dir nun eine kompatible Methode und weist diese der Event-Property zu.
type
(* Prototyp definieren, das "of object" kennzeichnet eine Methode *) TDataClickEvent = procedure(Sender: TObject; const Data: TDeineDaten) of object; TDeinFrame = class(TFrame) ... private (* privates Feld vom Typ des oben definierten Handlers *) FOnDataClick: TDataClickEvent; ... public (* und eine Property dazu *) property OnDataClick: TDataClickEvent read FOnDataClick write FOnDataClick; ... end; ... procedure TDeinFrame.OnIrgendwoGeklickt; begin (* wenn ein Handler zugewiesen wurde... *) if Assigned(FOnDataClick) then (* auslösen, die aktuellen Daten bilden die Parameter *) FOnDataClick(self, DatenausderKomponente); end;
Delphi-Quellcode:
type
TFormMain = class(TForm) ... private procedure MachWas(Sender: TObject; const Data: TDeineDaten); ... end; procedure TFormMain.MachWas(Sender: TObject; const Data: TDeineDaten); begin LabelDings.Caption := Data.Wasweißich; end; procedure TFormMain.FormCreate(Sender: TObject); begin DeinFrame.OnDataClick := MachWas; end; |
AW: Frame kann Objekte des Formulars nicht ändern
Nur mal so am Rande bemerkt, diese ganzen
Delphi-Quellcode:
Blöcke machen deinen Code sehr unleserlich weil hier vom Wesentlichen abgelenkt wird.
try..except
Vereinfache deinen Code durch Auslagerung in Funktionen
Delphi-Quellcode:
function VarFloatToStr( Value : Variant; Default : string = '' ) : string;
begin if VarIsFloat( Value ) then Result := FloatToStr( Value ) else Result := Default; end; function VarIntToStr( Value : Variant; Default : string = '' ) : string; begin if VarIsOrdinal( Value ) then Result := IntToStr( Value ) else Result := Default; end; function IfThen( ACondition : Boolean; const TrueStr : string; const FalseStr : string = '' ) : string; begin if ACondition then Result := TrueStr else Result := FalseStr; end; procedure TMain.Details_exec; begin Clear_Details; Label_ArtikelNr.Caption := Artikel.Artikel_Nr; Label_Bezeichnung1.Caption := Artikel.Bezeichnung1; Label_Gewicht.Caption := VarFloatToStr( Artikel.Gewicht, '-' ); Label_Sicherheitsbestand.Caption := VarIntToStr( Artikel.Sicherheitsbestand, '-' ); Label_AuftragNr.Caption := Auftrag.Auftrag_Nr; Label_Menge.Caption := VarIntToStr( Auftrag.Auftrag_Menge, '-' ); Label_AuftragStatus.Caption := VarIntToStr( Auftrag.Auftrag_Status, '-' ); Label_EilFA.Caption := IfThen( Auftrag.EilFa, 'Ja', 'Nein' ); Label_KritAT.Caption := VarFloatToStr( Auftrag.KritAT, '-' ); Label_Lagerzugang.Caption := DateToStr( Auftrag.Lagerzugang ); Label_AGStatus.Caption := VarIntToStr( Arbeitsgang.AG_Status, '-' ); Label_RMDatum.Caption := DateToStr( Arbeitsgang.RM_Datum ); Label_RMMenge.Caption := VarIntToStr( Arbeitsgang.RM_Menge, '-' ); Label_AGNr.Caption := VarIntToStr( Arbeitsgang.AG_Nr, '-' ); Label_AGBezeichnung.Caption := Arbeitsgang.AG_Bezeichnung; Label_Maschine.Caption := Arbeitsgang.Maschine_Bezeichnung; Label_MaschineNr.Caption := Arbeitsgang.Maschine_Nr; Label_Bezeichnung2.Caption := Artikel.Bezeichnung2; end; |
AW: Frame kann Objekte des Formulars nicht ändern
Zitat:
Nur der FormDesigner kann das "standardmäßig" nicht, bei der Bearbeitung der Frames. (da muß man den Fenster-Typ erst dem Delphi beibringen) Ach ja ... Try-Except bei der Typ-Umwandlung :wall: Wenn du soein Programm jemals debuggen musstest, dann willst'e den Verursacher dieses Codes erschießen. :oops: TryStrToInt und StrToIntDef PS: Das IfThen kennt XE5 bestimmt bereits. :angel: |
AW: Frame kann Objekte des Formulars nicht ändern
Zitat:
Ich dachte immer, einen
Delphi-Quellcode:
-Wert kann mann immer in einen
Integer
Delphi-Quellcode:
umwandeln, umgekehrt aber nicht.
string
Darum gibt es ja auch ![]() ![]() Hier liegen die Werte aber wohl als
Delphi-Quellcode:
vor, sonst ergibt es gar keinen Sinn ;)
Variant
Auch wenn es das ![]() |
AW: Frame kann Objekte des Formulars nicht ändern
Zitat:
|
AW: Frame kann Objekte des Formulars nicht ändern
Ups :oops: und achso, na dann. :mrgreen:
Zitat:
Notfalls lässt der sich noch recht leicht bei der IDE als Komponente registrieren. ( ![]() Mir ist aber so, als wenn das auch ohne Registrierung geht. :gruebel: Wenn der Frame aber selber eigene bearbeitbare Property enthalten soll, dann muß man den wohl ableiten und einen Vorfahr mit den Property als neues CustomModule (ala TForm, TDataModule, TFrame) beim Delphi registrieren. ![]() |
AW: Frame kann Objekte des Formulars nicht ändern
*doppelpost*
|
AW: Frame kann Objekte des Formulars nicht ändern
So zurück aus zwei Besprechungen...
Vielen Dank für die Antworten!!! Ich setze mich jetzt hin und versuche was zu lernen! Melde mich Gruß Patrick |
AW: Frame kann Objekte des Formulars nicht ändern
Hallo Zusammen,
@ Sir Rufus: Vielen Dank für die Vereinfachung. Sie gefällt miir auch wesentlich besser!!! @DeddyH und himutsu und ... Vielen Dank für die Erklärung! ich habe jetzt folgendes versucht: Frame_Uebersicht:
Delphi-Quellcode:
unit Frame_UebersichtUnit;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, AdvObj, BaseGrid, AdvGrid, Vcl.ExtCtrls, AdvGlowButton, Vcl.StdCtrls, AdvEdit, DBAdvEd, TGridDesignUnit, TAuftragUnit, Frame_DetailsUnit; type TEvent_Select = procedure(Sender: TObject; const Auftrag: TAuftrag) of object; //Hinzugefügt TFrame_Uebersicht = class(TFrame) Grid_Uebersicht: TAdvStringGrid; Panel_Titel: TPanel; Glow_Aktualisieren: TAdvGlowButton; Edit_Schnellsuche: TDBAdvEdit; procedure FrameResize(Sender: TObject); procedure Grid_UebersichtGetAlignment(Sender: TObject; ARow, ACol: Integer; var HAlign: TAlignment; var VAlign: TVAlignment); procedure Grid_UebersichtGetFloatFormat(Sender: TObject; ACol, ARow: Integer; var IsFloat: Boolean; var FloatFormat: string); procedure Grid_UebersichtGetCellColor(Sender: TObject; ARow, ACol: Integer; AState: TGridDrawState; ABrush: TBrush; AFont: TFont); procedure Grid_UebersichtClick(Sender: TObject); private { Private-Deklarationen } FOnDataClick: TEvent_Select; //Hinzugefügt public { Public-Deklarationen } property OnDataClick: TEvent_Select read FOnDataClick write FOnDataClick; //Hinzugefügt end; implementation {$R *.dfm} procedure TFrame_Uebersicht.Grid_UebersichtClick(Sender: TObject); begin Auftrag.Get_Auftrag(Grid_Uebersicht.Cells[1,Grid_Uebersicht.Row], Grid_Uebersicht.Cells[3,Grid_Uebersicht.Row]); if Assigned(FOnDataClick) then //hinzugefügt FOnDataClick(self, Auftrag); end; end. In dem Hauptformular:
Delphi-Quellcode:
type
TMain = class(TAdvToolBarForm) ... private { Private declarations } procedure Details_exec(Sender: TObject; const Auftrag: TAuftrag); //Abgeändert protected { Protected declarations } public { Public declarations } procedure Uebersicht_exec; procedure Clear_Details; end; var Main: TMain; implementation {$R *.dfm} procedure TMain.Uebersicht_exec; begin Uebersicht.Get_Uebersicht(User.User_ID); FillAdvGrid(Frame_Uebersicht1.Grid_Uebersicht, Uebersicht.Uebersicht_Cols, Uebersicht.Uebersicht_Rows); GridDesign.GridDesign(Frame_Uebersicht1.Grid_Uebersicht); end; procedure TMain.Details_exec(Sender: TObject; const Auftrag: TAuftrag); //abgeändert begin Clear_Details; Label_ArtikelNr.Caption := Artikel.Artikel_Nr; Label_Bezeichnung1.Caption := Artikel.Bezeichnung1; Label_Gewicht.Caption := VarFloatToStr( Artikel.Gewicht, '-' ); Label_Sicherheitsbestand.Caption := VarIntToStr( Artikel.Sicherheitsbestand, '-' ); Label_AuftragNr.Caption := Auftrag.Auftrag_Nr; Label_Menge.Caption := VarIntToStr( Auftrag.Auftrag_Menge, '-' ); Label_AuftragStatus.Caption := VarIntToStr( Auftrag.Auftrag_Status, '-' ); Label_EilFA.Caption := IfThen( Auftrag.EilFa, 'Ja', 'Nein' ); Label_KritAT.Caption := VarFloatToStr( Auftrag.KritAT, '-' ); Label_Lagerzugang.Caption := DateToStr( Auftrag.Lagerzugang ); Label_AGStatus.Caption := VarIntToStr( Arbeitsgang.AG_Status, '-' ); Label_RMDatum.Caption := DateToStr( Arbeitsgang.RM_Datum ); Label_RMMenge.Caption := VarIntToStr( Arbeitsgang.RM_Menge, '-' ); Label_AGNr.Caption := VarIntToStr( Arbeitsgang.AG_Nr, '-' ); Label_AGBezeichnung.Caption := Arbeitsgang.AG_Bezeichnung; Label_Maschine.Caption := Arbeitsgang.Maschine_Bezeichnung; Label_MaschineNr.Caption := Arbeitsgang.Maschine_Nr; Label_Bezeichnung2.Caption := Artikel.Bezeichnung2; end; procedure TMain.Clear_Details; begin Label_ArtikelNr.Caption:= ''; Label_Bezeichnung1.Caption:= ''; Label_Gewicht.Caption:= ''; Label_Sicherheitsbestand.Caption:= ''; Label_AuftragNr.Caption:= ''; Label_Menge.Caption:= ''; Label_AuftragStatus.Caption:= ''; Label_EilFA.Caption:= ''; Label_KritAT.Caption:= ''; Label_Lagerzugang.Caption:= ''; Label_AGStatus.Caption:= ''; Label_RMDatum.Caption:= ''; Label_RMMenge.Caption:= ''; Label_AGNr.Caption:= ''; Label_AGBezeichnung.Caption:= ''; Label_Maschine.Caption:= ''; Label_MaschineNr.Caption:= ''; Label_Bezeichnung2.Caption:= ''; Label_Gewicht.Caption:=''; end; procedure TMain.FormCreate(Sender: TObject); begin Frame_Uebersicht1.OnDataClick:=Details_exec(Frame_Uebersicht1.Grid_Uebersicht, Auftrag); //eingefügt end; end. Leider kann ich das so nicht kompilieren. Fehler:
Delphi-Quellcode:
[DCC Fehler] MainUnit.pas(356): E2010 Inkompatible Typen: 'TEvent_Select' und 'procedure, untyped pointer or untyped parameter'
Könnt Ihr mir noch ein bißchen weiterhelfen? Vielen Dank Patrick |
AW: Frame kann Objekte des Formulars nicht ändern
Du bekommst die Parameter im Event, daher kannst Du sie nicht setzen.
Delphi-Quellcode:
Damit sollte es gehen.
Frame_Uebersicht1.OnDataClick:=Details_exec;
|
AW: Frame kann Objekte des Formulars nicht ändern
Das hatte ich auch erst versucht. Aber dann kommt die Meldung:
Delphi-Quellcode:
Gruß Patrick
[DCC Fehler] MainUnit.pas(356): E2009 Inkompatible Typen: 'Liste der Parameter ist unterschiedlich'
|
AW: Frame kann Objekte des Formulars nicht ändern
TAuftrag ist in beiden Units exakt derselbe Typ?
|
AW: Frame kann Objekte des Formulars nicht ändern
Vergiss es!!!
ES KLAPPT!!! Jetzt versuche ich das Ganze noch besser zu verstehen. Das muss ich sicherlich noch 40 mal in der Software anwenden. Danach sollte ich es können. Vielen Dank für die Hilfe. Eventuell muss ich mich noch mal melden, wenn es die nächste Fälle - aber ich versuche es zu verstehen! Nochmal danke! Patrick |
AW: Frame kann Objekte des Formulars nicht ändern
TAuftrag ist ein Objekt mit den Auftragsdaten (Es gibt auch noch ein Objekt mit den Artikeldaten) und wo noch paar Proceduren sind. Diese Objekt liegen in eigenen Units und sind dort, wo sie benötigt werden eingebunden. Das heißt wenn ich in einer Unit das Objekt Auftrag:TAuftrag ändere und die Daten aktuelisiere, dann stehe die neuen Daten auch in den anderen Units, in denen die AUftragsUnit eingebunden steht, zur Verfügung.
So jedenfalls handle ich das derzeit, aber ich bin auch noch nicht soo fit ind OOP. Gruß Patrick |
AW: Frame kann Objekte des Formulars nicht ändern
Kann ich eigentlich das Objekt von TAuftrag mit über die Methode geben, ohne das TAuftrag im Hauptfenster eingebunden ist?
|
AW: Frame kann Objekte des Formulars nicht ändern
Wie soll das gehen? Das Hauptformular muss die Klasse ja kennen, mit der es arbeiten soll. Das mit den separaten Units für die gemeinsamen Klassen ist übrigens IMO genau die richtige Vorgehensweise.
|
AW: Frame kann Objekte des Formulars nicht ändern
Ich packe jede Klase in eine eigene Unit. Also habe ich für TArtikel und TAuftrag zwei Units... Dachte das ist übersichtlicher.
Gruß Patrick |
AW: Frame kann Objekte des Formulars nicht ändern
Ist doch vollkommen OK so.
|
AW: Frame kann Objekte des Formulars nicht ändern
Ich habe jetzt übrigens das Datenobjekt aus der Methode herausgenommen. Da die in dem Event des Frames das Datenobjekt aktualisiert wird und das Datenobjekt eh in jeder Unti mit eingefügt ist, brauche ich es nicht mit der Methode übergeben. Klappt wunderbar. Ich glaube die heutige Lektion hat mir viel gebracht!
Vielen Dank Patrick |
AW: Frame kann Objekte des Formulars nicht ändern
Und EventMethoden, welche über den OI zugewiesen werden sollen, müssen published sein.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:16 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz