Combobox /SLE Feld [ERLEDIGT]

Klassen, Objekte, Methoden, Instanzen

Moderator: Moderatoren

Combobox /SLE Feld [ERLEDIGT]

Beitragvon messing » Mo, 02. Apr 2012 12:04

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 13: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

Beitragvon messing » Mo, 02. Apr 2012 15:15

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

Beitragvon messing » Di, 03. Apr 2012 11:21

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
messing
Rekursionen-Architekt
Rekursionen-Architekt
 
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Re: Combobox /SLE Feld

Beitragvon brandelh » Di, 03. Apr 2012 11:35

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
brandelh
Foren-Moderator
Foren-Moderator
 
Beiträge: 13264
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim

Re: Combobox /SLE Feld

Beitragvon messing » Di, 03. Apr 2012 11:41

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
messing
Rekursionen-Architekt
Rekursionen-Architekt
 
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Re: Combobox /SLE Feld

Beitragvon brandelh » Di, 03. Apr 2012 13:14

Ich dachte eine Combobox :!: macht das automatisch, aber ich habe das nie benutzt, daher bin ich mir nicht sicher.
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
 
Beiträge: 13264
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim

Re: Combobox /SLE Feld

Beitragvon messing » Di, 03. Apr 2012 13:27

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
messing
Rekursionen-Architekt
Rekursionen-Architekt
 
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Re: Combobox /SLE Feld

Beitragvon brandelh » Di, 03. Apr 2012 14:14

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
brandelh
Foren-Moderator
Foren-Moderator
 
Beiträge: 13264
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim

Re: Combobox /SLE Feld

Beitragvon messing » Di, 03. Apr 2012 14:21

Hi Hubert,
:editbuffer()
müßte ich das in der Action oder im Datalink verwenden?
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

Beitragvon brandelh » Di, 03. Apr 2012 15:13

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
brandelh
Foren-Moderator
Foren-Moderator
 
Beiträge: 13264
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim

Re: Combobox /SLE Feld

Beitragvon messing » Di, 10. Apr 2012 13:58

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
messing
Rekursionen-Architekt
Rekursionen-Architekt
 
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Re: Combobox /SLE Feld

Beitragvon Tom » Di, 10. Apr 2012 14:46

Code: Alles auswählen
Eval(oBox:KillInputFocus)
Herzlich,
Tom
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
 
Beiträge: 6677
Registriert: Do, 22. Sep 2005 22:11
Wohnort: Berlin

Re: Combobox /SLE Feld

Beitragvon messing » Di, 10. Apr 2012 14:53

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
messing
Rekursionen-Architekt
Rekursionen-Architekt
 
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Re: Combobox /SLE Feld

Beitragvon Tom » Di, 10. Apr 2012 15:01

Es geht natürlich auch beispielsweise so:

Eval(aBoxes[i]: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
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
 
Beiträge: 6677
Registriert: Do, 22. Sep 2005 22:11
Wohnort: Berlin

Re: Combobox /SLE Feld

Beitragvon messing » Di, 10. Apr 2012 15:23

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

Beitragvon messing » Di, 10. Apr 2012 16:05

Hi,
läßt sich
Eval(aBoxes[i]: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
messing
Rekursionen-Architekt
Rekursionen-Architekt
 
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Re: Combobox /SLE Feld

Beitragvon Tom » Di, 10. Apr 2012 16:06

Wie sieht "aCombo" genau aus?
Herzlich,
Tom
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
 
Beiträge: 6677
Registriert: Do, 22. Sep 2005 22:11
Wohnort: Berlin

Re: Combobox /SLE Feld

Beitragvon AUGE_OHR » Di, 10. Apr 2012 18:44

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
AUGE_OHR
Marvin
Marvin
 
Beiträge: 10140
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg

Re: Combobox /SLE Feld

Beitragvon messing » Di, 10. Apr 2012 20:43

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
Benutzeravatar
messing
Rekursionen-Architekt
Rekursionen-Architekt
 
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen


Zurück zu OOP

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast