Announcement

Collapse
No announcement yet.

OnExit Nachfolgefeld disablen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • OnExit Nachfolgefeld disablen

    wie löst man am besten folgendes problem?<p>
    ich habe ein formular mit 3 edit - feldern. wenn die prüfenung des 1. feldinhaltes falsch ergibt, dann da soll das 2. feld auf enable = false gesetzt werden.<p>
    mein problem ist, daß onExit zu spät ist, um die prüfung durchzuführen. da hat delphi schon "beschlossen", auf das 2. feld zu springen. wenn ich dieses disable, wird nicht automatisch das 3. feld angesprungen.<p>
    hat schon jemand anders dieses problem gehabt und gelößt?

  • #2
    Kannst Du nicht onChange benutzen ? Dann kannst Du bei jeder Änderung entscheiden, ob das nächste Feld angesprungen werden sol

    Comment


    • #3
      leider nein. hier mein problem: <p>
      ich habe ein editfeld versandsart. dort wird die nummer der versandsart eingegeben. beim verlassen muss ich mit der nummer in der datenbank prüfen, ob zu dieser versandsart ein frächter im darauffolgenden editfeld eingegeben werden darf oder nicht.<p>
      onChange klappt da nicht, da ich erst die vollständig eingegebene nummer prüfen darf.<p&gt

      Comment


      • #4
        Wenn diese Nummer eine bestimmte Länge (= Anzahl Ziffern) oder eine bestimmte Syntax (012-3456-78-90) hat, dann könntest du trotzdem in "OnChange" prüfen, ob diese Bedingungen erfüllt sind.

        Vielleicht solltest du die Nachfolge-Edits generell erst mal abschalten. Sind dann obige Bedingungen erfüllt, bzw. findet das Programm die Nummer in der Datenbank, aktivierst du das jeweils folgende Control.

        Mathias

        Comment


        • #5
          leider hat die nummer werder einen bestimmten syntax oder eine bestimmte länge...<p>
          wenn ich das nachfolgende control erst onExit enable, dann wird es mir immer übersprungen, da ja vor dem onExit von delphi ermittelt wird, was das nächste enabled=true-control ist

          Comment


          • #6
            Dann könntest du zb. im onenter des zweiten feldes die Überprüfung vornehmen. Wenn diese dann nicht in Ordnung ist könntest Du mit mit Perform(WM_NEXTDLGCTL, 0, 0) zum nächsten Eingabefeld springen oder z.b. über edit1.setfocus gezielt den Fokus setzen

            Comment


            • #7
              die idee ist mir auch schon gekommen und hat nur noch einen kleinen schönheitsfehler, der aber ziemlich lästig ist. wenn ich dann im feld 3 bin und mit der shift + tab zurück will, dann lande ich im feld 2 und das OnEnter dort leitet den fokus wieder auf das feld 3..

              Comment


              • #8
                Dann erkläre doch mal bitte die genaue Sprungreihenfolge.<br>

                1 -> 2 Überprpfung falsch, dann zurück nach 1 oder weiter nach 3<br>
                3 -> 2 Überprpfung falsch, dann zurück nach 3 oder weiter nach 1<br&gt

                Comment


                • #9
                  Hallo,

                  bei diesem Problem sollte das folgende Beispielprojekt weiterhelfen:
                  <pre>
                  { ************************************************** **************
                  Source File Name : ValidateChildForm.PAS
                  Typ : Formular-unit
                  Autor : Andreas Kosch
                  Erstellt am : 04.05.96
                  Compiler : Delphi 3.0
                  Betriebssystem : Windows 95
                  Beschreibung : Demonstriert das Prüfen auf gültige Eingaben
                  für TEdit's mit Hilfe einer privaten Bot-
                  schaft. Über »ESC« kann der Anwender diese
                  Prüfung umgehen.
                  Revisionen : 16.04.97 Delphi 3.0
                  ************************************************** ************** }

                  unit ChildFrm;

                  interface

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

                  const
                  // Private Botschaft stößt die Eingabe-Validierung an
                  PM_Validate = WM_User + 1;

                  type
                  TFormChild = class(TForm)
                  Edit1: TEdit;
                  BitBtnOk: TBitBtn;
                  BitBtnCancel: TBitBtn;
                  Edit2: TEdit;
                  Label1: TLabel;
                  Label2: TLabel;
                  procedure Edit1Exit(Sender: TObject);
                  procedure FormActivate(Sender: TObject);
                  private
                  { Private-Deklarationen }
                  // Botschaftsbehandlungsmethode für die private Botschaft
                  procedure PMValidate(var M: TMessage); message PM_Validate;
                  public
                  { Public-Deklarationen }
                  end;

                  var
                  FormChild: TFormChild;

                  implementation

                  {$R *.DFM}

                  (* Sobald das TEdit den Eingabefokus verliert (der Anwender
                  wechselt zum nächsten Control), trifft das Ereignis »OnExit«
                  ein. Tatsächlich sind immer zwei Controls von »OnExit« be-
                  troffen, das nächste Control bekommt fast zeitgleich »OnEnter«
                  zugestellt. Es ist daher nicht zu empfehlen, in der Ereignis-
                  behandlungsmethode auf »OnExit« irgendeine Funktion aufzurufen,
                  die erneut einen Fokuswechsel hervorruft.
                  Genau diese Funktion wird jedoch benötigt. Hat der Anwender
                  eine ungültige Eintragung vorgenommen, darf er das Feld nicht
                  verlassen können. Statt dessen wird ein Hinweisfenster angezeigt
                  und der Fokus erneut in das fehlerhaft ausgefüllte TEdit-Feld
                  gesetzt.
                  Die Lösung für dieses Problem liegt darin, das sich das TEdit
                  selbst eine Botschaft schickt. Über den Aufruf von »PostMessage«
                  wird sichergestellt, daß die Botschaft erst an das Ende der
                  Botschaftswarteschlange einsortiert wird, d.h. die Botschaft wird
                  nicht sofort bearbeitet, so daß der Fokuswechsel bei »OnExit«
                  problemlos abläuft. In der Botschaftsbehandlungsmethode für die
                  private Botschaft wird die Benutzereingabe geprüft, liegt kein
                  gültiger Wert vor, so wird der Fokus zurück in das TEdit gesetzt.

                  Das Handle der eigenen Instanz wird über den zweiten Botschafts-
                  parameter »lParam« mit übergeben, so daß der Empfänger genau
                  weis, welches Control fokussiert werden soll.

                  Ausnahme : Der Anwender hat den Abbrechen-Button gedrückt,
                  in diesem Fall soll keine Validierung gestartet
                  werden. Beim Eintreffen von »OnExit« stellt das
                  Formular bereits in der Eigenschaft »ActiveControl«
                  das gerade aktivierte Control zur Auswertung bereit. *)

                  procedure TFormChild.Edit1Exit(Sender: TObject);
                  begin
                  if ActiveControl <> BitBtnCancel then
                  PostMessage(Handle, PM_Validate, 0, Longint(Sender));
                  end;

                  (* Im lParam-Parameter der private Botschaft PM_Validate wird
                  das Handle auf die TEdit-Instanz mitgeführt. Über Type-
                  casting klappt damit der Aufruf von »SetFocus«. *)

                  procedure TFormChild.PMValidate(var M: TMessage);
                  begin
                  // in lParam steht das Handle für das fehlerhafte TEdit
                  if not (TEdit(M.lParam).Text[1] = 'A') then begin
                  ShowMessage('Das erste Zeichen muß ein A sein!');
                  // Eingabefokus zurück in das fehlerhaft ausgefüllte Feld
                  TEdit(M.lParam).SetFocus;
                  end;
                  end;

                  (* Bei jedem Aktivieren des Formulars wird gleich der Eingabe-
                  fokus in das erste TEdit gelegt. *)

                  procedure TFormChild.FormActivate(Sender: TObject);
                  begin
                  Edit1.SetFocus
                  end;

                  end.
                  </pre>
                  Über <b>PostMessage</b> schickt sich das Formular eine private Botschaft, so dass die Prüfung "außerhalb" des Zeitfensters für den Fokuswechsel stattfindet und somit Win32 nicht durcheinanderkommt, wenn der Fokus zurückgesetzt wird. In der Botschaftsbehandlungsmethode kann man danach auch das 2. Editfeld sperren

                  Comment


                  • #10
                    kann es so klappen?<P>
                    <pre>
                    procedure TFormChild.PMValidate(var M: TMessage);
                    var
                    ok: Boolean;
                    begin
                    // in lParam steht das Handle für das zu früfende TEdit
                    if TEdit(M.lParam) = edFeld1 then
                    begin
                    // prüfung
                    OK := (edFeld1.Text[1] = 'A');
                    // wenn der fokus auf dem zutreffenden feld ist, und er nicht
                    // dort sein soll, dann auf das nächste feld senden
                    if (activeControl = edFeld2) and (not OK) then
                    Perform(WM_NEXTDLGCTL, 0, 0); // danke frank
                    // sperrung des feldes, wenn nötig
                    edFeld2.Enabled := OK;
                    end;
                    end;
                    </pre>

                    könnte man das ganze noch so hinbiegen, daß automatisch, immer wenn ein feld verlassen wird, die prüf-routine aufgerufen wird

                    Comment


                    • #11
                      das wars doch noch nicht ganz... <br>
                      wenn edFeld2.enabled = False ist und die prüfung ergibt, daß edFeld2 anzuspringen ist, dann ist zwar edFeld2 nach verlassen von edFeld1 wieder enabled, aber der focus steht auf edFeld3... <br&gt

                      Comment


                      • #12
                        Hab jetzt eine lösung...<p>
                        <pre>
                        procedure TForm1.CheckFieldExit(Sender: TObject);
                        var
                        OK: boolean;
                        begin
                        if sender = EnhEdit1 then
                        begin
                        OK := (EnhEdit1.StringValue = 'A');
                        if EnhEdit2.Enabled <> OK then
                        begin
                        if (ActiveControl = EnhEdit2) and (not OK) then
                        EnhEdit3.SetFocus;
                        EnhEdit2.Enabled := OK;
                        if (ActiveControl = EnhEdit3) and (OK) then
                        EnhEdit2.SetFocus;
                        end;
                        end;
                        end;
                        </pre>
                        <br>
                        diese funktion hat zwar noch den schönheitsfehler, daß die mousesteuerung nicht immer korrekt funtioniert, aber man kann nicht alles haben..

                        Comment

                        Working...
                        X