Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Prism Verständnisfrage zu Formular-Variable (https://www.delphipraxis.net/79816-verstaendnisfrage-zu-formular-variable.html)

gfjs 29. Okt 2006 07:25


Verständnisfrage zu Formular-Variable
 
Guten Morgen, allerseits.

Bei dem folgenden kurzen - aber weitgehend sinnfreien - Projekt:

Delphi-Quellcode:
unit uTestNEU;

interface

uses
  System.Drawing, System.Collections, System.ComponentModel,
  System.Windows.Forms, System.Data;

type
  NewLabel = System.Windows.Forms.&Label;
  LabelArray = array[0..10] of NewLabel;

  TestForm = class(System.Windows.Forms.Form)
  {$REGION 'Vom Designer verwalteter Code'}
  strict private
    /// <summary>
    /// Erforderliche Designervariable.
    /// </summary>
    Components : System.ComponentModel.Container;
    Button1: System.Windows.Forms.Button;
    Labels     : LabelArray;
    StartLabels : LabelArray;
    Dummy: System.Windows.Forms.Label;
    Num        : integer;
    TextBox1: System.Windows.Forms.TextBox;
    TextBox2: System.Windows.Forms.TextBox;
    /// <summary>
    /// Erforderliche Methode zur Unterstützung des Designers -
    /// ändern Sie die Methode nicht mit dem Quelltext-Editor
    /// </summary>
    procedure InitializeComponent;
    procedure Dummy_Click(sender: System.Object; e: System.EventArgs);
    procedure Button1_Click(sender: System.Object; e: System.EventArgs);
  {$ENDREGION}
  strict protected
    /// <summary>
    /// Ressourcen nach der Verwendung bereinigen
    /// </summary>
    procedure Dispose(Disposing: Boolean); override;
  private
    { Private-Deklarationen }
  public
    constructor Create;
  end;

var
  StartKonfig : LabelArray;

  [assembly: RuntimeRequiredAttribute(TypeOf(TestForm))]

implementation

{$AUTOBOX ON}

{$REGION 'Vom Windows Form-Designer erzeugter Code'}
/// <summary>
/// Erforderliche Methode zur Unterstützung des Designers --
/// ändern Sie die Methode nicht mit dem Quelltext-Editor
/// </summary>
procedure TestForm.InitializeComponent;
begin
  Self.Button1 := System.Windows.Forms.Button.Create;
  Self.Dummy := System.Windows.Forms.Label.Create;
  Self.TextBox1 := System.Windows.Forms.TextBox.Create;
  Self.TextBox2 := System.Windows.Forms.TextBox.Create;
  Self.SuspendLayout;
  // 
  // Button1
  // 
  Self.Button1.Location := System.Drawing.Point.Create(632, 16);
  Self.Button1.Name := 'Button1';
  Self.Button1.TabIndex := 0;
  Self.Button1.Text := 'Button1';
  Include(Self.Button1.Click, Self.Button1_Click);
  // 
  // Dummy
  // 
  Self.Dummy.Location := System.Drawing.Point.Create(616, 568);
  Self.Dummy.Name := 'Dummy';
  Self.Dummy.TabIndex := 1;
  Self.Dummy.Text := 'Dummy';
  Include(Self.Dummy.Click, Self.Dummy_Click);
  // 
  // TextBox1
  // 
  Self.TextBox1.Location := System.Drawing.Point.Create(568, 80);
  Self.TextBox1.Multiline := True;
  Self.TextBox1.Name := 'TextBox1';
  Self.TextBox1.Size := System.Drawing.Size.Create(100, 208);
  Self.TextBox1.TabIndex := 2;
  Self.TextBox1.Text := '';
  // 
  // TextBox2
  // 
  Self.TextBox2.Location := System.Drawing.Point.Create(568, 320);
  Self.TextBox2.Multiline := True;
  Self.TextBox2.Name := 'TextBox2';
  Self.TextBox2.Size := System.Drawing.Size.Create(100, 208);
  Self.TextBox2.TabIndex := 3;
  Self.TextBox2.Text := '';
  // 
  // TestForm
  // 
  Self.AutoScaleBaseSize := System.Drawing.Size.Create(6, 15);
  Self.ClientSize := System.Drawing.Size.Create(728, 616);
  Self.Controls.Add(Self.TextBox2);
  Self.Controls.Add(Self.TextBox1);
  Self.Controls.Add(Self.Dummy);
  Self.Controls.Add(Self.Button1);
  Self.Name := 'TestForm';
  Self.Text := 'WinForm';
  Self.ResumeLayout(False);
end;
{$ENDREGION}

procedure TestForm.Dispose(Disposing: Boolean);
begin
  if Disposing then
  begin
    if Components <> nil then
      Components.Dispose();
  end;
  inherited Dispose(Disposing);
end;

constructor TestForm.Create;
var
  i : integer;
begin
  inherited Create;
  //
  // Erforderlich für die Unterstützung des Windows Forms-Designers
  //
  InitializeComponent;
  //
  // TODO: Fügen Sie nach dem Aufruf von InitializeComponent Konstruktorcode hinzu.
  //
  num := 0;
  for i := 0 to 11 - 1 do
  begin
    Labels[i]     := NewLabel.Create;
    with Labels[i] do
    begin
      Text        := 'Label ' + i.ToString;
      Left        := 20;
      Top         := 20 + i*40;
      BackColor   := System.Drawing.Color.White;
      BorderStyle := System.Windows.Forms.BorderStyle.Fixed3D;
      Self.Controls.Add(Labels[i]);
      Include(Labels[i].Click, Self.Dummy_Click);
    end;
  end; // for i := 0 to 11 - 1 do
  StartLabels := Labels;
  StartKonfig := Labels;
end;

procedure TestForm.Button1_Click(sender: System.Object; e: System.EventArgs);
var
  i : integer;
begin
  TextBox1.Text := '';
  TextBox2.Text := '';
  for i := 0 to 11 - 1 do
  begin
    TextBox1.Text := TextBox1.Text + StartLabels[i].Text+#13#10;
    TextBox2.Text := TextBox2.Text + StartKonfig[i].Text+#13#10;
  end;
end;

procedure TestForm.Dummy_Click(sender: System.Object; e: System.EventArgs);
begin
  if Sender is System.Windows.Forms.&Label then
  (sender as System.Windows.Forms.&Label).Text := num.ToString;
  inc(num);
end;

end.
habe ich folgendes Problem:

Im contructor Create speichere ich die Eigenschaften der zur Laufzeit erzeugten Labels einmal in einer Formular-Variablen und einmal in einer globalen Variablen. Diese Variablen werden (so dachte ich zumindest) nur einmal in Create angesprochen. Mit Clicks auf die Label kann ich danndie Eigenschaft Text der Labels verändern. Ich war davon ausgegangen, dass ich den Zustand vor dem ersten Click in meinen beiden Variablen gespeichert habe und später darauf zugreifen kann. Wie ein Click auf Button 1 zeigt, ist dem aber nicht so.

Ich wäre dankbar, wenn mir jemand erklären könnte, warum das so ist und - genauso wichtig - wie ich den momentanen Stand so speichern kann, dass ich jederzeit wieder darauf zugreifen kann.

Vielen Dank im Voraus und noch einen schönen Sonntag.

Gruß Jürgen

Jürgen Thomas 29. Okt 2006 09:03

Re: Verständnisfrage zu Formular-Variable
 
Hallo Jürgen,

ich bin mir nicht sicher, ob ich Dein Problem richtig verstanden habe; aber auf jeden Fall hast Du folgende Probleme an den folgenden Stellen:
Delphi-Quellcode:
for i := 0 to 11 - 1 do
  begin
    Labels[i]     := NewLabel.Create;
    with Labels[i] do
    begin
      Text        := 'Label ' + i.ToString;
      Left        := 20;
      Top         := 20 + i*40;
      BackColor   := System.Drawing.Color.White;
      BorderStyle := System.Windows.Forms.BorderStyle.Fixed3D;
      Self.Controls.Add(Labels[i]);
      Include(Labels[i].Click, Self.Dummy_Click);
    end;
  end; // for i := 0 to 11 - 1 do
  StartLabels := Labels;
  StartKonfig := Labels;
  • Mit NewLabel.Create erzeugst Du ein Label, dessen Adresse (!) in Labels[i] gespeichert wird. (Der Compiler registriert wegen der Deklaration zusätzlich, dass diese Adresse auf ein Label verweist.)
  • Für das Array Labels wird automatisch der Platz für n Adressen reserviert; dieser Platz erhält selbst eine eigene Adresse.
  • Mit StartLabels := Labels; teilst Du dem Programm nur mit, dass unter der Adresse der Variablen StartLabels die Inhalte der Variablen Labels zu finden sind.
  • Mit StartKonfig := Labels; teilst Du dem Programm nur mit, dass unter der Adresse der Variablen StartKonfig die Inhalte der Variablen Labels zu finden sind.
Unter allen drei Array-Variablen finden sich also die gleichen 11 Labels. Wenn Du eines dieser Labels änderst, findest Du die Änderungen bei allen drei Array-Variablen wieder.

Für weitere Erläuterungen verweise ich Dich auf die [oh]NET-Doku:[/oh]
  • Array.Clone gibt Dir nähere Informationen zu Deinem Verfahren.
  • Array.Copy liefert (ohne dass ich es genauer durchdacht habe) wahrscheinlich wirklich die von Dir gewünschte Kopie.
Generell sind auch für Dein Verfahren die Klassen Array und ArrayList besser geeignet. Leider sind sie unter NET 1.1 von allgemeiner Struktur, und Du musst immer ein cast() anwenden. (Die generischen Klassen von NET 2.0 bieten mehr Möglichkeiten.)

Viel Erfolg! Jürgen

gfjs 30. Okt 2006 06:07

Re: Verständnisfrage zu Formular-Variable
 
Guten Morgen, Jürgen.

Vielen Dank für Deine ausführliche Antwort - ich werde mir das gleich mal näher ansehen.

Gruß Jürgen


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:47 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz