xbpPart in Abhängigkeit anzeigen

Grafische Primitive, XbaseParts und Darstellungsfragen allgemein.

Moderator: Moderatoren

Antworten
Benutzeravatar
Lutz Rübe
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 144
Registriert: Mi, 02. Aug 2006 18:13
Wohnort: 24536 Neumünster
Danksagung erhalten: 6 Mal
Kontaktdaten:

xbpPart in Abhängigkeit anzeigen

Beitrag von Lutz Rübe »

Hallo miteinander :) ,
nach längerer Zeit möchte ich euch mal wieder mit einer bzw. zwei Anfängerfragen belästigen. Bei der Durchsicht des Forums habe ich hier keine Hilfestellung gefunden, aber für euch Profis dürfte das eine Kleinigkeit bzw. Selbstverständlichkeit sein:

1. Fragestellung
ich möchte in einem Eingabefenster verschiedene XbpSle-Parts in Abhängigkeit von einer zuvor gemachten Eingabe anzeigen (bzw. editierbar) lassen.
Zum Beispiel: auf die Frage "Wieviel Tage möchtest Du sehen?" sollten in Abhängigkeit von der Antwort (z.b. "3") XbpSle's für die ersten drei Tage sichtbar sein, da die Eingaben für die Tage danach uninteressant bzw. überflüssig sind.

Ich muss also das Ergebnis des Frage-Sle's auswerten und anhand der Antwort die anderen sichtbar bzw. unsichtbar machen. Wie schaffe ich das ?

2. Fragestellung
Ich habe ein Eingabefenster, in dem Ergebnisse eingegeben werden sollen. In Abhängigkeit der Eingaben soll in einem Ergebnisfeld sofort nach der Eingabe oder Änderung eines Eingabefeldes in einem Ergebnisfeld sofort das Endergebnis angezeigt werden. Erst nach Drücken von "Enter" oder "Ok" können / sollen / dürfen die Ergebnisse in das Array bzw. die Datenbank abgespeichert werden.

Gibt es zu diesen beiden Fragestellungen kleine "Musterlösungen" ?

vielen Dank für auch noch so kleine Tipps.
Lutz
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2823
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 95 Mal
Danksagung erhalten: 13 Mal

Re: xbpPart in Abhängigkeit anzeigen

Beitrag von georg »

Hallo, Lutz -


es gibt Callback-Slots, wie z.B. :lostInputFocus(). Dort kannst Du die Eingabe prüfen und aufgrund dessen die erforderlichen XbpSLE sichtbar machen (oder verstecken). :show() und :hide() wären die Methoden der jeweiligen XbpSLE, die Du verwenden solltest.

Die zweite Frage verstehe ich nicht gut genug, um etwas zu antworten. Theoretisch kannst Du mittels des :keyBoard-Slots die Eingaben prüfen und schon während der Eingabe darauf reagieren. Wenn aber jemand "abc" eingibt, mag das Endergebnis ein anderes sein, als "ab" es ergeben würde. Daher wäre für mich eher das Verlassen des Feldes (:lostInputFocus) der Moment, etwas zu aktualisieren. Aber, wie geschrieben, ich verstehe die Implikationen Deiner 2. Frage nicht so ganz.
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21165
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 206 Mal
Danksagung erhalten: 67 Mal

Re: xbpPart in Abhängigkeit anzeigen

Beitrag von Manfred »

so wie ich Lutz verstehe, sollte ein Keyboard Slot für die Eingabe zuständig sein um entsprechende Ergebnisse direkt anzuzeigen und LostFocus dann für die Speicherung im Array, oder in einer DBF. Mit dem Keyboardslot würde aber dann (wie Georg schon schrieb) bei jedem Tastendruck eine Auswertung stattfinden und somit evtl. bei 10 Zeichen sich 10x der Ausgabewert verändern. Wenn Du das so willst.....
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: xbpPart in Abhängigkeit anzeigen

Beitrag von Tom »

Das kann man auch alles im Handler (also in der Eventloop) machen, der (die) einfach nur die EditBuffer() der verschiedenen Parts ausliest bzw. überprüft - und dann je nach Inhalt z.B. andere Parts mit Hide() und Show() (oder :Visible) zeigt/versteckt. Dadurch würden sich die Fenster/abhängigen Parts auch verändern, ohne dass man erst ein SLE verlassen muss. Aber es gibt mehrere Dutzend weiterer Möglichkeiten, um das gewünschte Verhalten zu erreichen.
Herzlich,
Tom
Benutzeravatar
Lutz Rübe
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 144
Registriert: Mi, 02. Aug 2006 18:13
Wohnort: 24536 Neumünster
Danksagung erhalten: 6 Mal
Kontaktdaten:

Re: xbpPart in Abhängigkeit anzeigen

Beitrag von Lutz Rübe »

Hallo Tom, Manfred und Georg,
vielen Dank für die Tips, die Hinweise gerade in Bezug auf Hide(), Show() und :visible sagen mir schon was, aber wie setze ich das um ? Mir fehlt da ein kleines Beispiel in Form von etwas Source-Code. Das gleiche gilt für den Keyboard Slot.

Ich bin nur ein Hobby-Programmierer, der sich alles selber beigebracht hat bzw. beibringen muss. Da wären praktische Beispiele für mich sehr, sehr hilfreich....

Besten Dank und schönen Abend noch
Gruß
Lutz
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2823
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 95 Mal
Danksagung erhalten: 13 Mal

Re: xbpPart in Abhängigkeit anzeigen

Beitrag von georg »

Uff, das so aus dem Ärmel schütteln ...

Code: Alles auswählen

aEntries := {}
oXbp := XbpSpinButton():new(oDlg, oDlg, aPos, aSize)
oXbp:killInputFocus := {|uNIL1, uNIL2, self| MacheSLEsAuf(self, aEntries)}
oXbp:create()
AAdd(aEntries, oXbp)
...
oXbp := XbpSLE():new(oDlg, oDlg, aPos, aSize)
...
oXbp:create():hide()
AAdd(aEntries, oXbp)
...
Damit hast Du Deine Eingabe-Elemente sowie ein Array, das jedes Eingabe-Element in einem Array-Element hat, vergleichbar der GetList bei Cl*pper.

Bitte: das ist mein Stil zu programmieren. Der ist weder besonders originell oder effizient, sondern einfach nur mein Stil.

Code: Alles auswählen

FUNCTION MacheSLEsAuf(oSLE, aEntries)
  Local nEntries, nI
  nEntries := oSLE:editBuffer()
  IF nEntries < 1
    RETU(.F.)
  ENDIF
  FOR nI := 2 TO 11
    aEntries[nI]:hide()
  END
  FOR nI := nEntries + 1 to 11
    aEntries[nI]:show()
  END
RETURN(.T.)
Ich unterstelle, dass es ein XbpSpinButton gibt, über das angegeben wird, wieviele XbpSLE "offen" sein sollen. Dann unterstelle ich, dass es derer 10 Stück gibt, also insgesamt 11 Xbase-Parts.

Zuerst verstecke ich alle XbpSLE() (erster FOR-Loop), dann öffne ich die XbpSLE, die sichtbar sein sollen (zweiter FOR-Loop).

Der Code ist nicht vollständig und möglicherweise auch nicht fehlerfrei, sollte Dir aber eine Idee geben, wie man mit dem Callback-Slot umgeht.
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: xbpPart in Abhängigkeit anzeigen

Beitrag von AUGE_OHR »

wenn man den Formdesigner verwendet und man ein FELD per DragDrop einfügt dann wird jedes SLE in das Array aEditcontrol aufgenommen. das Array hat nun den Vorteil das du "in einem Satz" folgendes machen kannst

Code: Alles auswählen

AEVAL(aEditcontrol, {|o| o:SetData() })  // o:datalink "setzen" -> Control Wert zuweisen
AEVAL(aEditcontrol, {|o| o:GetData() })  // o:datalink "lesen"  -> Control Wert auslesen
weiteres Beispiel

Code: Alles auswählen

AEVAL(aEditcontrol, {|o| o:Hide()    })  // alle Controls verstecken
AEVAL(aEditcontrol, {|o| o:Show()    })  // alle Controls anzeigen
selbstverständlich kannst du auch "einzeln" mit jedem Array Element = Object arbeiten.

---

praktisch jedes XbPart hat ein o:Keyboard Callback Slot.

ein Typische Einsatz des o:Keyboard Callback Slot wäre ein ENTER zum aktivieren eines XbpPushbutton()

Code: Alles auswählen

oPb:keyBoard := { |nKey,uNIL,oSelf| IF( nKey = xbeK_ENTER, PostAppEvent( xbeP_Activate,,,oSelf ), NIL ) }
für ein inkrementelles suchen in einem Browse könnte es so aussehen.

Code: Alles auswählen

// Taste im Browse gedrückt
::Keyboard := { |nKey,uNIL,oSelf| ::Key2board( nKey ) }

METHOD VYBN2:Key2board( nKey )

   ::cSeekTXT += CHR( nKey )            // Such String  
   ::SearchTXT:setCaption( ::cSeekTXT ) // Anzeige Begriff 

   IF VALTYPE( &( ORDKEY() ) ) = "N"
      DBSEEK( VAL( ::cSeekTXT ) )
   ELSEIF VALTYPE( &( ORDKEY() ) ) = "C"
      DBSEEK( UPPER( ::cSeekTXT ) )
   ENDIF

   ::refreshAll()                       // Browse Anzeige  
   postAppEvent( xbeBRW_ItemMarked, NIL, NIL, self )
gruss by OHR
Jimmy
Benutzeravatar
Lutz Rübe
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 144
Registriert: Mi, 02. Aug 2006 18:13
Wohnort: 24536 Neumünster
Danksagung erhalten: 6 Mal
Kontaktdaten:

Re: xbpPart in Abhängigkeit anzeigen

Beitrag von Lutz Rübe »

erst einmal herzlichen Dank an alle für die Tipps und Info's.

Den Vorschlag von Georg konnte ich schon erfolgreich umsetzen, jetzt feile ich da an der Feinarbeit. Bei den Tipps von Jimmy weiß ich noch nicht, wie ich da die Bedingung (zum Beispiel "If spinbar = 6, then show() SLE(1) bis SLE(6) endif") umsetzen kann. Ich habe da so meine Probleme mit dem Aeval-Command.

Bei meiner 2. Aufgabe, habe ich nur numerische Felder, 12 davon sind reine Eingabefelder, Feld Nr 13 ist die Summe aus den Felder Nr. 3, 6, 9 und 12. Die Felder 14 - 26 sind Rechenfelder, deren Inhalt aus den Feldern 1 - 13 auf unterschiedeliche Weise errechnet werden (nur die 4 Grundrechenarten + 1 Fixwert). Ihr sprecht von :keyboard callstacks, aber das sagt mir garnichts, mit denen habe ich noch nicht gearbeitet..
Gibt es da nicht ein kurzes Beispiel in der Form: Eingabefeld 1 + Eingabefeld 2 = Ausgabefeld 3 ??

Vielen Dank nochmal für die Hilfe bei meinem ersten "Fall".

Danke und viele Grüße - zur zeit von der Insel Föhr -
Lutz
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: xbpPart in Abhängigkeit anzeigen

Beitrag von AUGE_OHR »

Lutz Rübe hat geschrieben: Mo, 06. Nov 2017 9:45Ich habe da so meine Probleme mit dem Aeval-Command.
du musst ja nicht (immer) AEVAL() verwenden ... eine FOR / NEXT tut es auch.
es geht nur um das Prinzip von Objecten die man gut in einem Array "sammeln" kann.
Lutz Rübe hat geschrieben:Bei meiner 2. Aufgabe
zunächst einmal : wir arbeiten unter Windows und da gibt es "keine Reihenfolge" da der User mit der Maus "überall" hin klicken könnte.

somit ist ein WHEN / VALID nur als Simulation zu sehen wo man mit den Callback Slots

Code: Alles auswählen

   o:setInputFocus  := {| uNIL1, uNIL2, self | ... }
   o:killInputFocus := {| uNIL1, uNIL2, self | ... }
hantiert.
mit o:editable := .T./.F. oder o:Enable() / o:Disable() kann man das "ein/aus" schalten simulieren damit nur bestimmte Eingabefelder aktive sind.

---

IMHO rate ich dringend zu CLASS Code ... da hat man die iVAR praktisch wie eine "Fieldwide STATIC" im PRG -> keine Parameter Übergabe an interne Method notwendig.

---

der Formdesigner hat ja die iVAR aEditControl welches XbpSLE Objecte aufnimmt. grundsätzlich kann man auch alle anderen XbParts so behandeln.für WHEN / VALID könnte man die Callback Slots so bestücken

Code: Alles auswählen

   AEVAL(::aEditControl, { |o,i| o:setInputFocus  := {|u1,u2,oSelf| ::CheckWHEN(oSelf,i)  }
   AEVAL(::aEditControl, { |o,i| o:killInputFocus := {|u1,u2,oSelf| ::CheckVALID(oSelf,i) }
man simuliert es jeweils durch eine eigene Method

Code: Alles auswählen

METHOD My_Dialog:CheckVALID(oSelf,i)
LOCAL cVar1, cVar2, cVar3, cVar4, cVar5, cVar6 ... 
   DO CASE
      CASE oSelf:isDerivedFrom( "XbpSLE" )
         IF EMPTY(oSelf)
            SetAppFocus(oSelf) // go back
            RETURN
         ENDIF
         DO CASE
            CASE i = 1  // Nummer des XbpSLE ( Reihenfolge wie o:Create() )
               // alles Type String !  
               cVar1 := oSelf:EditBuffer()
               cVar5 := ::aEditControl[5]:EditBuffer()
               ...
 
      CASE oSelf:isDerivedFrom( "XbpSpinbutton" )
im Gegensatz zu o:GetData() wird mit o:Editbuffer() kein o:Datalink ausgeführt sodass man es nur zum validieren benutzen sollte !

! Tip : bei einem Array für die "Nummer" eine #define verwenden

Code: Alles auswählen

#define VorName 5
               cVar5 := ::aEditControl[VorName]:EditBuffer()
gruss by OHR
Jimmy
Antworten