Frage

Ich muss oft einen Dialog im Delphi/C ++ -Builder entwerfen, mit dem verschiedene Eigenschaften eines Objekts geändert werden können, und der Code, der ihn verwendet, sieht normalerweise so aus.

Dialog.Edit1.Text := MyObject.Username;
Dialog.Edit2.Text := MyObject.Password;
// ... many more of the same

if (Dialog.ShowModal = mrOk) 
begin
  MyObject.Username := Dialog.Edit1.Text;
  MyObject.Password := Dialog.Edit2.Text;
  // ... again, many more of the same
end;

Ich brauche auch oft einen ähnlichen Code, um Objekte zu/von XML/INI-Files/was auch immer zu marken.

Gibt es gemeinsame Redewendungen oder Techniken, um diese Art von einfachem, aber sich wiederholenden Code zu vermeiden?

War es hilfreich?

Lösung

Nun, etwas, von dem ich völlig von unschätzbarem Wert fühle, ist das Gexperts Plugin -Assistent "Reverse Anweisung", der nach der Installation von Gexperts durch Drücken von Shift + Alt + R aufgerufen wird

Was es tut, ist automatisch die Aufgaben für den hervorgehobenen Block umzuschalten. Zum Beispiel:

edit1.text := dbfield.asString;

wird

dbField.asString := edit1.text;

Nicht genau das, wonach Sie suchen, sondern eine große Zeitsparung, wenn Sie eine große Anzahl von Aufgaben haben.

Andere Tipps

Hier ist meine Variation dazu. Was ich getan habe, nachdem ich den gleichen sich wiederholenden Code satt hatte, war, alle Bearbeitungsfelder gemäß den XML -Knotennamen zu benennen, die ich wollte, dann um die Komponenten umzusetzen und ihre Werte auszugeben. Der XML -Code sollte offensichtlich sein, und ich habe nur ein Bearbeiten und ein Kontrollkästchen, aber Sie sollten in der Lage sein, die Idee zu sehen.

procedure TfrmFTPSetup.LoadFromXML(szFileName : string);
var
xComponent : TComponent;
nLoop : Integer;
xMainNode : TXmlNode;
xDocument : TNativeXml;
begin
inherited;

xDocument := TNativeXml.Create;
try
    xDocument.LoadFromFile(szFileName);
    xMainNode := xml_ChildNodeByName(xDocument.Root, 'options');
    for nLoop := 0 to ComponentCount - 1 do
    begin
        xComponent := Components[nLoop];
        if xComponent is TRzCustomEdit then
        begin
            (xComponent as TRzCustomEdit).Text := xMainNode.AttributeByName[xComponent.Name];
        end;
        if xComponent is TRzCheckBox then
        begin
            (xComponent as TRzCheckBox).Checked := xml_X2Boolean(xMainNode.AttributeByName[xComponent.Name], false);
        end;
    end;
finally
    FreeAndNil(xDocument);
end;
 end;

   procedure TfrmFTPSetup.SaveToXML(szFileName : string);
var
xComponent : TComponent;
nLoop : Integer;
xMainNode : TXmlNode;
xDocument : TNativeXml;
begin
inherited;

xDocument := TNativeXml.CreateName('ftpcontrol');
try
    xMainNode := xml_ChildNodeByNameCreate(xDocument.Root, 'options');
    for nLoop := 0 to ComponentCount - 1 do
    begin
        xComponent := Components[nLoop];
        if xComponent is TRzCustomEdit then
        begin
            xMainNode.AttributeByName[xComponent.Name] := (xComponent as TRzCustomEdit).Text;
        end;
        if xComponent is TRzCheckBox then
        begin
            xMainNode.AttributeByName[xComponent.Name] := xml_Boolean2X((xComponent as TRzCheckBox).Checked);
        end;
    end;

    xDocument.XmlFormat := xfReadable;
    xDocument.SaveToFile(szFileName);
finally
    FreeAndNil(xDocument);
end;
 end;

Es wird nicht als gute Praxis angesehen, auf Eigenschaften visueller Komponenten in einem Formular zuzugreifen. Es wird als besser angesehen, separate Eigenschaften zu haben. Im obigen Beispiel hätten Sie Benutzername und Kennworteigenschaften mit GET -and -Set -Methoden.

Zum Beispiel:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
  private
    function GetPassword: string;
    function GetUsername: string;
    procedure SetPassword(const Value: string);
    procedure SetUsername(const Value: string);
  public
    property Password: string read GetPassword write SetPassword;
    property Username: string read GetUsername write SetUsername;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function TForm1.GetPassword: string;
begin
 Result := Edit2.Text;
end;

function TForm1.GetUsername: string;
begin
 Result := Edit1.Text;
end;

procedure TForm1.SetPassword(const Value: string);
begin
  Edit2.Text := Value;
end;

procedure TForm1.SetUsername(const Value: string);
begin
  Edit1.Text := Value;
end;

end.

Dies bedeutet, dass Sie die visuellen Komponenten im Formular ändern können, ohne dass es den aufrufenden Code beeinflusst.

Eine andere Option wäre, das Objekt als Eigenschaft an den Dialog zu übergeben.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TUserObject = class(TObject)
  private
   FPassword: string;
   FUsername: string;
  public
   property Password: string read FPassword write FPassword;
   property Username: string read FUsername write FUsername;
  end;

  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    btnOK: TButton;
    procedure btnOKClick(Sender: TObject);
  private
    FUserObject: TUserObject;
    procedure SetUserObject(const Value: Integer);
  public
    property UserObject: Integer read FUserObject write SetUserObject;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.btnOKClick(Sender: TObject);
begin
 FUserObject.Username := Edit1.Text;
 FUserObject.Password := Edit2.Text;
 ModalResult := mrOK;
end;

procedure TForm1.SetUserObject(const Value: Integer);
begin
 FUserObject := Value;
 Edit1.Text := FUserObject.Username;
 Edit2.Text := FUserObject.Password;
end;

end.

Ich hoffe, das hilft.

Delphi hat zumindest "mit", obwohl es das Problem nicht vollständig löst.

if (Dialog.ShowModal = mrOk) 
begin
  with MyObject do
  begin
    Username := Dialog.Edit1.Text;
    Password := Dialog.Edit2.Text;
    // ... again, many more of the same
  end;
end;

Und Builder Afaik hat nichts Ähnliches.

Bindungssteuerungen an Daten funktionieren in Delphi gut, aber leider nur dann, wenn diese Daten in einem tdataset -Nachkommen liegen. Sie können einen Tdataset -Nachkomme schreiben, der ein Objekt für die Datenspeicherung verwendet, und es stellt sich heraus, dass eine solche Sache bereits existiert. Siehe Link unten ... Diese Implementierung scheint nur mit Sammlungen von Objekten (TCollection oder Tobjectlist) zu funktionieren, nicht mit einzelnen Objekten.

http://www.torry.net/pages.php?id=563 - Suchen Sie nach "Snap -Object -Datensatz" die Seite nach "Snap -Objekt -Datensatz"

Ich habe keine persönlichen Erfahrungen damit, aber es wäre sehr nützlich, wenn es funktioniert und insbesondere wenn es auch mit einzelnen Objektinstanzen wie einer Eigenschaft auf einem Datenmodul funktioniert ...

Sieh nach oben "Mediatormuster". Es ist ein GOF -Designmuster, und in ihrem Buch motiviert das GOF dieses Designmuster mit einer etwas ähnlichen Situation wie das, was Sie hier beschreiben. Es zielt darauf ab, ein anderes Problem zu lösen - Kopplung - aber ich denke, Sie haben haben Auch dieses Problem sowieso.

Kurz gesagt, die Idee ist, einen Dialogmediator zu erstellen, ein zusätzliches Objekt, das zwischen allen Dialogwidgets sitzt. Kein Widget kennt ein anderes Widget, aber jedes Widget kennt den Mediator. Der Mediator kennt alle Widgets. Wenn ein Widget ändert, informiert es den Mediator; Der Mediator informiert dann die relevanten Widgets darüber. Wenn Sie beispielsweise auf OK klicken, kann der Mediator andere Widgets über dieses Ereignis informieren.

Auf diese Weise kümmert sich jeder Widget nur um Ereignisse und Handlungen, die nur mit sich selbst zusammenhängen. Der Mediator kümmert sich um die Interaktion zwischen allen Widgets, sodass all dieser "Boilerplate" -Coder über alle Widgets aufgeteilt wird, und der "Rückstand", der global für alle Widgets ist, ist die Interaktion und liegt in der Verantwortung des Vermittlers.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top