AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

OnChangeValue ?

Ein Thema von akurka · begonnen am 13. Jan 2016 · letzter Beitrag vom 18. Jan 2016
Antwort Antwort
Seite 1 von 5  1 23     Letzte »    
Benutzerbild von akurka
akurka

Registriert seit: 30. Dez 2008
Ort: Schweiz, 8636 Wald ZH
81 Beiträge
 
Delphi 7 Personal
 
#1

OnChangeValue ?

  Alt 13. Jan 2016, 10:23
Hallo
Ich suche eine Komponente die bei ànderung einer Variable (Externe Eingangswert) einen Event auslöst. Etwa in der Art : OnChangeValue.

Ich habe überall danach gesucht aber niergens gefunden.
Muss ich dann eine eigene Komponente schreiben ?
Anton Kurka
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.176 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: OnChangeValue ?

  Alt 13. Jan 2016, 10:29
Mach das doch mit einer Property dessen Setter-Methode ein "OnChange"-Event auslöst:

Delphi-Quellcode:
  TMeineKlasse = class
     private
      var FMeinWert: Integer;
      procedure setMeinWert(const value: Integer);
     public
      var OnValueChange: TNotifyEvent;
      property MeinWert: Integer read FMeinWert write setMeinWert;
  end;

procedure TMeineKlasse.setMeinWert(const value: Integer);
begin
   if (FMeinWert = value) then Exit;
   FMeinWert := value;
   if Assigned(OnValueChange) then OnValueChange(self);
end;
  Mit Zitat antworten Zitat
Perlsau
(Gast)

n/a Beiträge
 
#3

AW: OnChangeValue ?

  Alt 13. Jan 2016, 13:36
Zur Ergänzung: Man schreibt sich dann eine Ereignisbehandlung, z.B.:
Delphi-Quellcode:
procedure TFormMain.ExternValueChanged;
begin
  DoSomething;
end;
und weist z.B. im OnCreate oder im OnShow der Form dem Ereignis diese Methode zu:
Delphi-Quellcode:
procedure TFormMain.FormCreate(Sender: TObject);
begin
  OnValueChange := ExternValueChanged;
end;
Wird das Ereignis in einer anderen Unit bzw. Form ausgelöst, muß man darauf achten, daß diese andere Form bereits instaziiert wurde. Wird sie erst nach der Unit/Form, in der die Ereignisbehandlung steht, erzeugt, wählt man für die Zuweisung der Ereignisbehandlung zum Ereignis z.B. OnShow oder OnActivate statt OnCreate.
  Mit Zitat antworten Zitat
Benutzerbild von akurka
akurka

Registriert seit: 30. Dez 2008
Ort: Schweiz, 8636 Wald ZH
81 Beiträge
 
Delphi 7 Personal
 
#4

AW: OnChangeValue ?

  Alt 13. Jan 2016, 14:13
Hallo, danke für die beiden Beiträge.

Was den Setter anbelangt verstehe ich es nicht ganz, der Wert den ich überwachen will kommt von aussen, d.h es wird in meinem Programm gar nicht
verändert resp. gesetzt.
Im meinem Programm wird das Wert nur gelesen.

Ich meinte Setter bedeutet setzen eines bestehenden
Wertes und wenn es ungültig ist dann eine Exception auslösen. Verstehe ich es falsch ??

Beim zweitem Vorschlag was meinst Du mit DoSomething ?
Sollte da ein Vergleich zwischen AltWert und NeuWert statfinden ?
Aber wie soll daraus ein Event erzeugt werden ?
Anton Kurka
  Mit Zitat antworten Zitat
Zoot

Registriert seit: 30. Jan 2006
Ort: Hessen
113 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: OnChangeValue ?

  Alt 13. Jan 2016, 14:51
Beim zweitem Vorschlag was meinst Du mit DoSomething ?
Delphi-Quellcode:
procedure TFormMain.DoSomething;
Var i : integer
begin
 for i := 0 to 999999 do
 begin
  beep;
  Sleep(1000);
 end;
end;
  Mit Zitat antworten Zitat
Perlsau
(Gast)

n/a Beiträge
 
#6

AW: OnChangeValue ?

  Alt 13. Jan 2016, 16:57
Was den Setter anbelangt verstehe ich es nicht ganz, der Wert den ich überwachen will kommt von aussen, d.h es wird in meinem Programm gar nicht
verändert resp. gesetzt. Im meinem Programm wird das Wert nur gelesen.
Du schreibst den Wert, der überwacht werden soll, doch in eine Variable, nicht wahr? Und diese Variable deklarierst du nun als Property. Properties (Eigenschaften) liest und schreibt man über Getter und Setter. Dabei stellt der Name (Bezeichner) des Properties die "von außen" ansprechbare Variable dar. Die "eigentliche" Variable, die den Wert tatsächlich vorhält, wird nach den Regeln der Code-Formatierung mit einem vorangestellten f gekennzeichnet:
Delphi-Quellcode:
Private
  fMeinWert : Integer;

Public
  Property MeinWert : Integer read GetfMeinWert write SetfMeinWert;
Das ist die Art & Weise, wie man Properties erstellt. Drückst du nun in der Zeile, in der das Property deklariert wird, die Tastenkombination Shift-Control-C, werden automatisch die beiden Methoden Getter und Setter erstellt. Nun kannst du "von außen" die Variable fMeinWert nur noch auf dem Weg über das Property ändern:
Delphi-Quellcode:
// Wert setzen
MeinWert := 65; //oder
MeinWert := AusgelesenerWert;
// Wert auslesen
MeineVariable := MeinWert;
Beim Setzen und Auslesen von MeinWert werden jetzt immer Setter und Getter des Properties aufgerufen. Hier kannst du dann z.B. das reinschreiben, was passieren soll, wenn sich die Variable ändert, also im Setter nach der Zuweisung DoSomeThing.

Ich meinte Setter bedeutet setzen eines bestehenden Wertes und wenn es ungültig ist dann eine Exception auslösen. Verstehe ich es falsch ??
Nein, Setter ist einfach die Methode, um den privaten Integer fMeinWert zu schreiben. Wenn du einer Variablen einen Wert zuweist, passiert ja sonst nichts. Wenn du einem Property einen Wert zuweist, kannst du im Setter zusätzliche Befehle unterbringen.

Beim zweitem Vorschlag was meinst Du mit DoSomething ?
DoSomething ist einfach das, was beim Setzen des Wertes passieren soll, eine Dummy-Procedure, da ich ja nicht wissen kann, was du da vorhast, wenn der Wert gesetzt wird.

Sollte da ein Vergleich zwischen AltWert und NeuWert statfinden ?
Das weiß ich doch nicht, was da stattfinden soll, das mußt du doch selber wissen. Du hattest doch oben geschrieben, du möchtest, daß etwas bestimmtes ausgeführt wird, wenn sich der eingelesene Wert ändert, nicht? Okay, dann schreibst du in den Setter das rein, was dann ausgeführt werden soll, am besten in einer eigenständigen Methode, die du dann im Setter aufrufst, was ich mit DoSomething quasi als Dummy bereits vorgeführt habe.

Aber wie soll daraus ein Event erzeugt werden ?
Ein Event – auf deutsch: ein Ereignis – mußt du nur dann erzeugen, wenn du Unit-übergreifend arbeitest. Mit anderen Worten: Befindet sich das Property in derselben Unit, in der sich auch die Methode, mit der auf die Änderung des Wertes reagiert werden soll, befindet, brauchst du kein Ereignis, dann kannst du das dort direkt erledigen. Befindet sich das Property jedoch in einer eigenständigen Unit, muß die Unit, die die Reaktions-Methode enthält, ja irgendwie mitbekommen, daß sich der Wert geändert hat. Zu diesem Zweck wurden die Events erfunden. Ein Event wird erst einmal als Typ deklariert, gewöhnlich vor der Typdeklaration der Klasse, wie ich dir anhand eines Beispiels zeigen möchte, in welchem das Ereignis in der Klasse TDatMod (UnitData) stattfindet:
Delphi-Quellcode:
TYPE
  TUpdateStatusbarEvent = Procedure of Object; // Statusbar in Mainform

TYPE
  TDatMod = CLASS(TDataModule)
  ...
  PRIVATE { Private-Deklarationen }
    Var
      fUpdateStatusbar : TUpdateStatusbarEvent;
  ...
  PUBLIC { Public-Deklarationen  }
    ...
    Property OnUpdateStatusbar : TUpdateStatusbarEvent read fUpdateStatusbar write fUpdateStatusbar;
    ...
  END;
Ausgelöst wird das Ereignis dann durch diesen Befehl: If Assigned(fUpdateStatusbar) Then fUpdateStatusbar; Verbindest du nun in deiner Unit, in der die Reaktions-Methode steht, das Ereignis mit der Methode, wird diese Methode jedesmal aufgerufen, wenn das Ereignis stattfindet – oder wie man hier gewöhnlich sagt: wenn das Event feuert:
Delphi-Quellcode:
Procedure TFormMain.FormActivate(Sender: TObject);
begin
  ...
  DatMod.OnUpdateStatusbar := StatusBarAktuell;
  ...
end;
Ich setze dieses Event z.B. ein, um in der Mainform die Statusbar zu aktualisieren, wenn sich der Datensatzzeiger einer Tabelle geändert hat:
Delphi-Quellcode:
Procedure TDatMod.View_LogAccessAfterScroll(DataSet: TDataSet);
begin
  If Assigned(fUpdateStatusbar) Then fUpdateStatusbar;
end;
Damit wird nun jedesmal beim Scrollen einer Datenmenge, die z.B. in FormMain durch das Scrollen in einem DBGrid ausgelöst wurde, die Anzeige in der Methode StatusBarAktuell aktualisiert:
Delphi-Quellcode:
Procedure TFormMain.StatusBarAktuell;
begin
  StatBar.Panels[0].Text := GLD.IntToStrPunkte(DatMod.View_LogAccess.RecNo);
  StatBar.Panels[1].Text := GLD.IntToStrPunkte(DatMod.View_LogAccess.FieldByName('ID').AsInteger);
  StatBar.Panels[2].Text := DatMod.View_LogAccess.FieldByName('DATEI').AsString;
  Application.ProcessMessages;
end;
Solltest du entgegen meiner Erwartung nur Bahnhof verstehen, empfiehlt sich die Lektüre des einen oder anderen Tutorials, z.B. das beim Delph-Treff über Klassen und Objekte.
  Mit Zitat antworten Zitat
Benutzerbild von akurka
akurka

Registriert seit: 30. Dez 2008
Ort: Schweiz, 8636 Wald ZH
81 Beiträge
 
Delphi 7 Personal
 
#7

AW: OnChangeValue ?

  Alt 13. Jan 2016, 17:27
Hallo
Vielen vielen Dank für die ausführliche Erklärung.
Es ist sehr gut erklärt, soweit habe ich es verstanden.

Ich hatte die überwachte Werte bisher über mehrere Timer überwacht was im prinzip einem Polling gleichkommt, und natürlich auch dem Windows Prinzip wiederspricht.

Jetzt werde ich mein Programm entsprechend umstellen, ich schreibe Dir
dann ob es klappt.
Besten Dank und ein Gruss aus dem Wolkenverhangenem Engadin
Anton
Anton Kurka
  Mit Zitat antworten Zitat
Benutzerbild von akurka
akurka

Registriert seit: 30. Dez 2008
Ort: Schweiz, 8636 Wald ZH
81 Beiträge
 
Delphi 7 Personal
 
#8

AW: OnChangeValue ?

  Alt 13. Jan 2016, 18:33
Hallo Perlsau

Leider klappt es bereits bei der Deklaration nicht :
Delphi-Quellcode:
unit menueREF;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,ExtCtrls,
  NC__09,NC__08,NCAS09,NCKU00,NCKU09;

type
  TForm2 = class(TForm)
    Image1: TImage;
    procedure MenueCreate(Sender: TObject);
    procedure StatusBild;
    procedure Man;
    procedure MenueDestroy(Sender: TObject);
    procedure OnKeyPress(Sender: TObject; var Key: Char);
  private
    fBWStellung: Integer;
    { Private-Deklarationen }
  public
    Property BWStellung :Integer read GetfBWStellung write SetfBWStellung;
    { Public-Deklarationen }
  end;

var
  Form2: TForm2;
  ActiveImage :TImage;
  BWStellung := int(Status.CNC.ZBETR); //Status.CNC.ZBETR ist Byte
  F_KeyA :boolean;
  procedure OptionFehlt;

implementation
{$R *.dfm}
uses NCUP01,NCUP10,NCUP11,NCUP12,NCUP13;
//=====================================================
procedure TForm2.MenueCreate(Sender: TObject);
begin
  keypreview:=true;
usw.....
Bei der Compilation gibt es diese Meldung:
[Fehler] menueREF.pas(22): Feld- oder Methodenbezeichner erwartet

Eigentlich ist der zu überwachende Wert ein Byte (STATUS.CNC.ZBETR).
Ich habe es zuerst mit Byte probiert danach auch mit integer.
Es wird ein Feld verlangt also z.Bsp ein String
Muss ich meine Variable als String deklarieren d.h. Feld?
oder liegt sm am DELPHI7 dass es nicht schluckt ?
Gruss Anton
Anton Kurka
  Mit Zitat antworten Zitat
Perlsau
(Gast)

n/a Beiträge
 
#9

AW: OnChangeValue ?

  Alt 13. Jan 2016, 18:45
Ich sehe in deinem Code keine Getter- und Setter-Methoden. Die erzeugst du, wie ich oben bereits ausgeführt habe, indem du den Cursor auf die Zeile mit der Property-Deklaration setzt und die Tastenkombi Ctrl-Shift-C drückst. In den Setter schreibst du dann rein, was passieren soll, wenn der Wert gesetzt wird.

Hinweis: Eine Anleitung sollte man schon komplett ausführen, weil sonst Fehlermeldungen auftreten.
  Mit Zitat antworten Zitat
Benutzerbild von akurka
akurka

Registriert seit: 30. Dez 2008
Ort: Schweiz, 8636 Wald ZH
81 Beiträge
 
Delphi 7 Personal
 
#10

AW: OnChangeValue ?

  Alt 13. Jan 2016, 20:13
Hallo Perlsau
Tut mir leid dass ich Dich nochmal beanspruche aber es haut nicht.
Muss man für die Setter Deklaration immer eigene Klasse deklarieren
oder kann ich auch bestehende nehmen ? Ich habe beides probiert
aber ohne Erfolg. Was mache ich falsch ?

Delphi-Quellcode:
unit menueREF;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,ExtCtrls,
  NC__09,NC__08,NCAS09,NCKU00,NCKU09;

type
  TForm2 = class(TForm)
    Image1: TImage;
    procedure MenueCreate(Sender: TObject);
    procedure OnValueChange;
    procedure StatusBild;
    procedure Man;
    procedure MenueDestroy(Sender: TObject);
    procedure OnKeyPress(Sender: TObject; var Key: Char);
  private
     //fBWStellung: Integer;
     //procedure setBWStellung(const value: Integer);
    { Private-Deklarationen }
  public
      //OnValueChange :TNotifyEvent;
      //Property BWStellung :Integer read GetfBWStellung write SetfBWStellung;
    { Public-Deklarationen }
  end;

  TMeineKlasse = class
    private
       fBWStellung: Integer;
       procedure setBWStellung(const value: Integer);
    public
      OnValueChange :TNotifyEvent;
      Property BWStellung :Integer read getfBWStellung write SetfBWStellung;
    end;


var
  Form2: TForm2;
  ActiveImage :TImage;
  F_KeyA :boolean;
  procedure OptionFehlt;

implementation
{$R *.dfm}
uses NCUP01,NCUP10,NCUP11,NCUP12,NCUP13;
//=====================================================
//procedure TForm2.setBWStellung(const value: Integer);
procedure TMeineKlasse.setBWStellung(const value: Integer);
begin
  if (fBWStellung = value) then Exit;
    fBWStellung := value;
  if Assigned(OnValueChange) then
    OnValueChange(Self);
end;
//-------------------------------------------------
procedure TForm2.OnValueChange;
begin
  StatusBild;
end;
//====================================================
procedure TForm2.MenueCreate(Sender: TObject);
begin
  keypreview:=true;
  //BWStellung := int(Status.CNC.ZBETR);
  ActiveImage :=Image1;
  Form2.ClientWidth:=512;
  Form2.ClientHeight:=256;
  Form2.Image1.Width:=511;
  Form2.Image1.Height:=255;
  F_obereAchsen:=false;
  F_KeyA := false;
end;
//=====================================================
procedure TForm2.MenueDestroy(Sender: TObject);
die Fehler Meldung ist die gleiche :
[Fehler] menueREF.pas(35): Feld- oder Methodenbezeichner erwartet

Gruss
Anton
Anton Kurka
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 5  1 23     Letzte »    

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:30 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