Combobox /SLE Feld [ERLEDIGT]

Klassen, Objekte, Methoden, Instanzen

Moderator: Moderatoren

Antworten
Benutzeravatar
messing
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Combobox /SLE Feld [ERLEDIGT]

Beitrag von messing »

Servus, habe mit

Code: Alles auswählen

   #pragma Library( "XppUI2.LIB" )
   #pragma Library( "Adac20b.lib" )
   #include "Appevent.ch"
   #include "Xbp.ch"
   PROCEDURE Main
      LOCAL nEvent, mp1, mp2, oXbp, bAction
      LOCAL oCombo, i, aData, bData
      aData := { "Montag" , "Dienstag", "Mittwoch", "Donnerstag", ;
                 "Freitag", "Samstag" , "Sonntag" }

      SetColor("N/W")
      CLS
      SetAppWindow():clipChildren := .F.
      SetAppWindow():configure()
      oCombo      := XbpCombobox():new()
      oCombo:type := XBPCOMBO_DROPDOWN
      oCombo:create( ,, {10, 220}, {150, 150} )
      ArrayToComboBox( oCombo, aData )
      bData := {|x| IIf( x==NIL ,oCombo:Xbplistbox:getitem(1), x:=oCombo:Xbplistbox:getitem(x)) }
      oCombo:XbpSle:dataLink := bData
      oCombo:XbpSle:setData()
      bAction := {|mp1, mp2, obj| obj:XbpListbox:getData(), ;
                  DispoutAt( MaxRow(), 0, obj:Xbplistbox:getdata()) }
      oCombo:XbpListbox:ItemMarked := bAction
      oCombo:XbpListbox:ItemSelected := bAction
      aData := NIL

      nEvent := 0
      DO WHILE nEvent <> xbeP_Close
         nEvent := AppEvent( @mp1, @mp2, @oXbp )
         oXbp:HandleEvent( nEvent, mp1, mp2 )
      ENDDO
   RETURN
Jetzt hab ich den Effekt, mach ich die Box auf und wandere mit der Maus drüber, verändert sich der Index ohne Mausklick, wander ich von der offenen Box in einen anderen Part, bleibt im SLE Feld die alte Anzeige, aber der Index hat sich verändert.
Hab ich einen Codeblock vergessen?
Zuletzt geändert von messing am Mo, 30. Apr 2012 14:10, insgesamt 3-mal geändert.
Gruß
Bruno
Messing
Benutzeravatar
messing
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Re: Combobox /SLE Feld

Beitrag von messing »

Habe mit

Code: Alles auswählen

      bData :={|x| IIf( x==NIL ,oCombo:Xbplistbox:getitem(1),;
       x:=oCombo:Xbplistbox:getitem(len(oCombo:XbpListbox:getdata()))) }
und

Code: Alles auswählen

      bAction := {|mp1, mp2, obj| oCombo:XbpSle:getdata(), ;
                  aArray:=oCombo:XbpListbox:getdata(),;
                  cText:=oCombo:XbpListbox:getitem(aArray[len(aArray)]),;
                  oCombo:XbpSle:setdata(cText)}
erstmal das Problem gelöst.
Wenn jetzt die Maus durch die Liste fährt, dann verändert sich sofort das SLE Feld.
Gruß
Bruno
Messing
Benutzeravatar
messing
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Re: Combobox /SLE Feld

Beitrag von messing »

Servus,
habe die Combobox soweit fertig

Code: Alles auswählen

      oCombo      := XbpCombobox():new()
      oCombo:type := XBPCOMBO_DROPDOWN
      oCombo:create( ,, {10, 220}, {150, 150} )
      ArrayToComboBox( oCombo, aData )
      bData :={|x| IIf( x==NIL ,oCombo:Xbplistbox:getitem(1),;
               oCombo:Xbplistbox:getitem(len(oCombo:XbpListbox:getdata()))) }

      oCombo:XbpSle:dataLink := bData
      oCombo:XbpSle:setData()

      bAction := {|mp1, mp2, obj| obj:XbpSle:getdata(), ;
                  obj:XbpSle:setdata(obj:XbpListbox:getitem(obj:XbpListbox:getdata();
                  [len(obj:XbpListbox:getdata())])),abc:=oCombo:getdata()}

      oCombo:XbpListbox:ItemMarked := bAction
      oCombo:XbpListbox:ItemSelected := bAction
Jetzt hab ich das Problem, das bei einer Eingabe im SLE Feld ein Fehler Auftritt: Fehler bei der Arrayindizierung !
Jetzt bräuchte ich mal Unterstützung, was muß dazu, bzw. abgeändert werden, das bei eingabe im Sle Feld bei "Sonntag" wird "xSonntag" draus, das Sle Feld gelöscht wird und der eingegebene Buchstabe auf die Listbox zugreift, "Buchstabe - Zum nächsten Eintrag mit diesem Anfangsbuchstaben gehen"
Gruß
Bruno
Messing
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Combobox /SLE Feld

Beitrag von brandelh »

Zunächst solltest du mal die codeblocks nicht so ausufern lassen ;-)

Code: Alles auswählen

bAction := {|mp1, mp2, obj| obj:XbpSle:getdata(), ;
                  obj:XbpSle:setdata(obj:XbpListbox:getitem(obj:XbpListbox:getdata();
                  [len(obj:XbpListbox:getdata())])),abc:=oCombo:getdata()}
nutze darin Funktionen (verwendbar für viele Fenster) oder Methoden (Aktion ist speziell für ein Fenster).

Code: Alles auswählen

bAction := {|mp1, mp2, obj|  MachIrgendWas(obj,mp1,mp2, self }  // rufe im Codeblock eine Funktion mit den nötigen Parametern (self = Fenster)

function MachIrgendWas(obj,mp1,mp2, oWin }
     local cTemp, aAuswahl
     cTemp := obj:XbpSle:getdata()
     ... prüfen oder per debugger was passiert ...
     aAuswahl := obj:XbpListbox:getdata()
     *** Ist kein Eintrag markiert, wird ein leeres Array zurückgegeben. !!!
     if len(aAuswahl)=0 
        **** hier entsteht wohl bisher deine Fehlermeldung - oder später ... abfangen
     else
        **** was auch immer du willst....
      obj:XbpSle:setdata(obj:XbpListbox:getitem(obj:XbpListbox:getdata();
                  [len(obj:XbpListbox:getdata())])),abc:=oCombo:getdata()
:idea: tue dir selbst den Gefallen und programmiere einfachen Code :!:

Spätestens bei einer späteren Wartung wirst du dir selbst dafür danken ;-)
Gruß
Hubert
Benutzeravatar
messing
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Re: Combobox /SLE Feld

Beitrag von messing »

Hi Hubert,
ja richtig, werde eine Funktion draus machen, nur wie bekomm ich es hin das bei einer Eingabe im Sle Feld diese als Suchfunktion in der Listbox arbeitet? In der Doku steht das bei XbpListBox der Buchstabe verwendet wird um auf das nächste Element mit dem Buchstaben zu springen.
Gruß
Bruno
Messing
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Combobox /SLE Feld

Beitrag von brandelh »

Ich dachte eine Combobox :!: macht das automatisch, aber ich habe das nie benutzt, daher bin ich mir nicht sicher.
Gruß
Hubert
Benutzeravatar
messing
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Re: Combobox /SLE Feld

Beitrag von messing »

Hi Hubert,
Nein, eine Combobox besteht aus XbpSle und XbpListbox. Wenn die Listbox offen ist wird bei Eingabe des Buchstabens der Nächste Eintrag markiert, welcher den Buchstaben am Anfang hat. Wenn jedoch der Cursor im SLE Feld ist, zählt dies für das SLE Feld und nicht für die dazugehörige Listbox. Ich hab zwar jetzt mit

Code: Alles auswählen

   oCombo:keyboard      := {|nKey,mp2,obj| keytest(nKey,mp2,obj)}
FUNCTION keytest(nKey,mp1,obj)

xyz:= chr(nKey)
yxz:= mp1
zxy:= obj
obj:XbpSle:setdata(xyz)
if obj:listboxfocus()=.F.
obj:listboxfocus(.T.)
PostAppEvent(nKey,,,obj:Xbplistbox)
else
obj:listboxfocus(.F.)
obj:listboxfocus(.T.)
PostAppEvent(nKey,,,obj:Xbplistbox)
endif
RETURN
erstmal erreicht, das die Markierung auf dem Buchstaben entsprechenden Element steht, jedoch sind jetzt die Bewegungsmöglichkeiten über Pfeiltaste, in der Listbox nicht mehr möglich.
Ich vermute mal, das im datalink eine Änderung stattfinden muß, damit die Bewegungsmöglichkeiten über Pfeiltasten in der Listbox weiterhin funktionieren.
Gruß
Bruno
Messing
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Combobox /SLE Feld

Beitrag von brandelh »

bei solchen Aktionen ist es wichtig, dass der Inhalt vom SLE nicht mit getData() (*** führt Datalink aus !) sondern mit :editBuffer() ausgeführt wird.
Die Keyboard und appevent() Kombination ist schon ausgereizt. Nicht falsch, aber schwer zu beherrschen.
Ich persönlich nutze für diese Aktionen lieber :setData() oder :setTopItem() um ein Element auszuwählen bzw. zu scrollen.
Den Textinhalt der ListBox speichere ich auch in einem Array, so kann ich schnell ermitteln, welches Element ich brauche.
Gruß
Hubert
Benutzeravatar
messing
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Re: Combobox /SLE Feld

Beitrag von messing »

Hi Hubert,
:editbuffer()
müßte ich das in der Action oder im Datalink verwenden?
Gruß
Bruno
Messing
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Combobox /SLE Feld

Beitrag von brandelh »

nicht im datalink. :editBuffer() wird an Stelle von :getData() verwendet, wenn keinesfalls gespeichert werden soll,
sondern du nur auf den Inhalt eines Controll reagieren willst. Möglicherweise brauchst du es gar nicht, denn du nutzt den Keyboard slot.
Wenn do dort aber den aktuellen Inhalt des SLE wissen willst, ist :editBuffer() genau richtig.
Gruß
Hubert
Benutzeravatar
messing
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Re: Combobox /SLE Feld

Beitrag von messing »

Servus, muß nochmal an die Combobox!
Über die Slots lassen sich diverse Actionen ausführen, wie ist das jedoch, wenn man die Box nich anklickt?
Was müßte ich machen, das wenn die Box nicht angecklickt wurde, trotzdem die funktion für den killinputfocus ausgeführt wird?
z.B. Wenn ich einen Kunden in der Box stehen hab, brauch ich diesen ja nicht mehr auswählen. Nur müßte die selbe Action ausgeführt werden, welche durch den Focuswechsel gemacht wird.
Gruß
Bruno
Messing
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: Combobox /SLE Feld

Beitrag von Tom »

Code: Alles auswählen

Eval(oBox:KillInputFocus)
Herzlich,
Tom
Benutzeravatar
messing
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Re: Combobox /SLE Feld

Beitrag von messing »

Danke,
ich hab vier Comboboxen, muß ich diese einzeln bennen: oCombo1,oCombo2... oder funktioniert das auch über das Array aCombo, in dem ich die vier Combos aufbewahre? Ich hab mir gedacht, was mit aEditcontrols und SLE, mach ich mit aCombo mit Combos.
Kunde, Fahrzeug,etc. werden nur bei der ersten Eingabe bzw. Auswahl gewählt, danach kommen die restlichen Eingabe welche sich ändern und somit über die Focussteuerung berechnungen, etc ausführen.
Gruß
Bruno
Messing
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: Combobox /SLE Feld

Beitrag von Tom »

Es geht natürlich auch beispielsweise so:

Eval(aBoxes:KillInputFocus)

"KillInputFocus" ist ja ein Slot des Objekts bzw. der Klasse, also letztlich eine Instanzvariable, deren Inhalt evaluiert wird, wenn einer vorhanden ist und das entsprechende Event eintritt. Mit dem Codeblock darin kannst Du tun und lassen, was Du möchtest, ihn also auch einfach auslösen, solange das Objekt existiert. Objekte werden, wenn sie in Arrays "gespeichert" werden, lediglich referenziert; es werden keine Kopien abgelegt.
Herzlich,
Tom
Benutzeravatar
messing
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Re: Combobox /SLE Feld

Beitrag von messing »

Danke,
ich meinte nicht das die Combos im Array sind, hab mich falsch ausgedrückt, aber ich glaube schon, das du das durch den Vergleich mit EditControl so angenommen hast. :D
Gruß
Bruno
Messing
Benutzeravatar
messing
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Re: Combobox /SLE Feld

Beitrag von messing »

Hi,
läßt sich
Eval(aBoxes:KillInputFocus)
wie müßt ich das in AEVAL einsetzen,

Code: Alles auswählen

AEval(aCombo,{|x|Eval(x:KillInputFocus)})
bringt Fehlermeldung, ich hab im :killinputfocus

Code: Alles auswählen

      oCombo:killInputFocus := ;
          { |x,y,obj| kfzarray:=kfzeingabe->(Comboende(obj)) }
in der Funktion lese ich die Daten aus der DBF ein, zwecks Weiterverarbeitung

Code: Alles auswählen

Function Comboende(obj)
local aArray,nData

nData:=val(right(obj:getData(),4),4)
if(nData=0,dbgotop(),dbgoto(ndata))
 aArray:=scatter()
return aArray
Ich hab in der Combobox Werte aus der DBF plus die Recno() angehängt

Code: Alles auswählen

FUNCTION RecordData(cFeld)
LOCAL n ,aData
//:= Array( FCount() )
if isnull(cFeld)
   aData:= Array( FCount() )
   FOR n:=1 TO FCount()
      aData[ n ] := FieldGet(n)
   NEXT
else
   aData:={}
   aadd(aData,fieldget(fieldpos(cFeld))+"     "+strzero(recno(),4))
//aData:={alltrim(fieldget(fieldpos(cFeld))),recno()}
endif
RETURN aData
und habe somit direkten Zugriff auf den Datensatz zum einlesen der weiteren Daten. Wenn ich die entsprechende Combobox verlasse wird ordnungsgemäß der Block und somit die Funktion ausgeführt. Wenn ich die Daten der Combobox Box weiter benötige und keine neue Auswahl treffe, wollte ich per Pushbutton, im Nachhinein den Fokuswechsel auslösen.
Gruß
Bruno
Messing
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: Combobox /SLE Feld

Beitrag von Tom »

Wie sieht "aCombo" genau aus?
Herzlich,
Tom
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: Combobox /SLE Feld

Beitrag von AUGE_OHR »

messing hat geschrieben:ja richtig, werde eine Funktion draus machen, nur wie bekomm ich es hin das bei einer Eingabe im Sle Feld diese als Suchfunktion in der Listbox arbeitet? In der Doku steht das bei XbpListBox der Buchstabe verwendet wird um auf das nächste Element mit dem Buchstaben zu springen.
ändere doch mal

Code: Alles auswählen

oCombo:type := XBPCOMBO_DROPDOWN
auf

Code: Alles auswählen

oCombo:type := XBPCOMBO_DROPDOWNLIST
Nachtrag: wenn du wirklich mit dem SLE "selbst" was machen willst dann siehe dir Workaround PDR 3277 an
gruss by OHR
Jimmy
Benutzeravatar
messing
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Re: Combobox /SLE Feld

Beitrag von messing »

Hi Tom,
erstelle OBJ mit

Code: Alles auswählen

      cFeld:="KD_BEZ"
      aData := kundeneingabe->(RecordAllData(cFeld))
      bData :={|x| IIf( x==NIL ,oCombo:Xbplistbox:getitem(1),;
               oCombo:Xbplistbox:getitem(len(oCombo:XbpListbox:getdata()))) }
      bAction := {|mp1,mp2,obj,self| ComboAction(mp1,mp2,obj,self)}


   oCombo := XbpCombobox():new( drawingArea, , {8,352}, {184,168}, { { XBP_PP_BGCLR, XBPSYSCLR_ENTRYFIELD }, { XBP_PP_FGCLR, GRA_CLR_BLACK } } )
   oCombo:tabstop := .T.
      oCombo:type := XBPCOMBO_DROPDOWN
   oCombo:create()
      ArrayToComboBox( oCombo, aData )
      oCombo:XbpSLE:dataLink := bData
      oCombo:XbpSLE:setData()
      oCombo:ItemMarked := bAction
      oCombo:ItemSelected := bAction
      oCombo:killInputFocus := ;
          { |x,y,obj| kundenarray:=kundeneingabe->(Comboende(obj)) }
      aadd(aCombo,oCombo)

mit cFeld bennen ich das Feld, wo die Daten ins aData reinsollen, aData benutze ich dann für die Auswahl.
Durch RecordAllData(cFeld) wird die Bezeichnung und die Recno() in das aData übernommen

Code: Alles auswählen

FUNCTION RecordAllData(cFeld)
// Komplette DBF einlesen
aAllData := {}
dbgotop()
Do While !Eof()
  aAdd(aAllData,RecordData(cFeld))

  DbSKip()
ENDDO
RETURN aAllData
und

Code: Alles auswählen

FUNCTION RecordData(cFeld)
LOCAL n ,aData
//:= Array( FCount() )
if isnull(cFeld)
   aData:= Array( FCount() )
   FOR n:=1 TO FCount()
      aData[ n ] := FieldGet(n)
   NEXT
else
   aData:={}
   aadd(aData,fieldget(fieldpos(cFeld))+"     "+strzero(recno(),4))
//aData:={alltrim(fieldget(fieldpos(cFeld))),recno()}
endif
RETURN aData
das sieht dann in der Liste etwa so aus "Name 0004". Mit bDAta sorge ich dafür, das Listeneintrag 1 im SLE Feld steht. Hier ArraytoComboBox

Code: Alles auswählen

     FUNCTION ArrayToComboBox( oCombo, aArray )
      LOCAL i:=0, imax := Len(aArray)
      IF Valtype( aArray[1] ) = "A"    // 2-dim Array
         DO WHILE ++i <= imax           // Erste Spalte übertragen
            oCombo:addItem( aArray[i,1] )
         ENDDO
      ELSE                              // 1-dim Array
         DO WHILE ++i <= imax           // Arrayelemente übertragen
            oCombo:addItem( aArray[i] )
         ENDDO
      ENDIF
   RETURN oCombo
FUNCTION ComboAction(mp1,mp2,obj,oWin)
local cTemp, aAuswahl,abc
zzz:=obj:XbpSle:editbuffer()

abc:=LastAppEvent()
cTemp := obj:XbpSle:getdata()
     aAuswahl := obj:XbpListbox:getdata()
     if len(aAuswahl)=0
     obj:listBoxFocus(.T.)
     PostAppEvent(abc)
     else
obj:XbpSle:setdata(obj:XbpListbox:getitem(obj:XbpListbox:editbuffer();
                  [len(obj:XbpListbox:getdata())]))

ENDIF
RETURN NIL
Function Comboende(obj)
local aArray,nData

nData:=val(right(obj:getData(),4),4)
if(nData=0,dbgotop(),dbgoto(ndata))
 aArray:=scatter()
// aArray:=recorddata()
return aArray

, Das ist alles für die Combobox. Mit AAdd(aCombo,oCombo) füge ich den Eintrag ins Array a Combo. Der Aufbau des Array ist dem des Editcontrol gleich, nur das ich die Comboboxen halt in aCombo eingetragen hab. Alle vier Comboboxen benutzen den selben Block bei

Code: Alles auswählen

      aData := kundeneingabe->(RecordAllData(cFeld))
      bData :={|x| IIf( x==NIL ,oCombo:Xbplistbox:getitem(1),;
               oCombo:Xbplistbox:getitem(len(oCombo:XbpListbox:getdata()))) }
      bAction := {|mp1,mp2,obj,self| ComboAction(mp1,mp2,obj,self)}
Nur aData und killinputfocus verändert sich, da es vier DBF sind "Kunde, Transart,Kennzeichen,Fahrer". Ich benutze aData nur zum füllen der Combobox:XbpListbox und killinputfocus für das holen der Daten aus der DBF

Code: Alles auswählen

      oCombo:killInputFocus := ;
          { |x,y,obj| kundenarray:=kundeneingabe->(Comboende(obj)) }
.ist geändert auf transarray,kfzarray und fahrerarray.
Ich hoffe, die Erklärung reicht, um zu verdeutlichen wie aCombo aussieht.
Gruß
Bruno
Messing
Antworten