Get Blogged by JoKi

"The only frontiers are in your mind"
28 | 05 | 2017
Navigation
Syndication
Latest Tweets

Most Read Articles
Article Time Line
About me
Family guy, geek, entrepreneur, software craftsman: Visual FoxPro, C#, SQL Server, MySQL, Linux consultant, conference speaker

Certificates & Awards

Microsoft Certified Professional

Microsoft Specialist - Programming in HTML5 with JavaScript and CSS3 Specialist

Get in touch

Sharing is caring

Recent books


Sponsoring
If you like the information on these pages, your support is highly appreciated.
Thank you very much!
Affiliates

 

Spacer for layout formatting

Die Checkbox und ihr Enter/Return-Verhalten

User Rating:★★★★★ / 4
PoorBest 
Development 17 August 2006 - 

Das Problem

Heute mal wieder etwas aus der Programmierküche mit dem Fuchs. Ausgehend von einer Anforderung in einem laufenden Projekt sollte es ermöglicht werden, dass man innerhalb eines VFP Grids sowohl mit der Tab-Taste wie auch der Enter-Taste durch die Zellen navigieren kann. Nun, soweit stellt dies eigentlich kein Problem dar.

Interessant wird es erst im Zusammenspiel mit anderen Klassen als Control der Spalte. Etwa der Checkbox. Das normale Verhalten der Checkbox bei Tasteneingaben in Visual FoxPro sieht kurz gesagt so aus:

Space - Änderung des Zustands
Tab - Wechsel zum nächsten Control ohne Statusänderung
Enter/Return - Wechsel zum nächsten Control mit Änderung des Zustands

Nun gut, damit kann man leben und das Verhalten erscheint auf den ersten Blick intuitiv. Nur... wir wollen innerhalb des Grid nur Navigieren und nicht den Zustand der Checkbox verändern.

Die erste Idee

Jedem Fuchs wird auf Anhieb einfallen, dass die Lösung des Problems in der Überlagerung der Checkbox.KeyPress() Ereignismethode zu realisieren. Das ist auch vollkommen korrekt und okay. Mein erster Ansatz ergab sich aus einer kurzen Recherche samt Bestätigung im FoxWiki. Der Quellcode sah im ersten Ansatz so aus:

*====================================================================
* Erweiterung: Die Return/Enter-Taste soll keine Funktion besitzen.
* Das Problem ist, dass primär mit der Enter- neben der
* Tab-Taste in den Formularen und Grids navigiert wird.
*====================================================================
LPARAMETERS nKeyCode, nShiftAltCtrl

  If (m.nKeyCode == 13 .And. InList(m.nShiftAltCtrl, 0, 1)) .Or. ;
    (m.nKeyCode == 10 .And. m.nShiftAltCtrl == 2) ;

    Keyboard '{TAB}'
    NoDefault
    Return
  EndIf

  DoDefault()

Wir verändern das Verhalten der Checkbox soweit, dass die Enter/Return-Taste ihre Funktionalität verliert und der Wechsel durch das Auslösen der Tab-Taste wiederhergestellt wird. Ein kurzer Test mit der erweiterten Klasse auf einem Formular funktioniert soweit tadellos. Fein...

Das Extra - VFP Grid

Frohen Mutes wird diese Klasse nun als CurrentControl in eine Gridspalte eingebaut und getestet. Das Ergebnis ist katastrophal! Neben der Tatsache, dass der Zustand der Checkbox geändert wird, wechseln wir nicht nur in die nächste Spalte, nein, sondern in die übernächste. Na ganz toll...

Nun, was ändert sich den wirklich? Beim Steppen im Debugger ergibt sich, dass das Checkbox.Value nicht verändert wird. Soweit entspricht dies der Verwendung auf einem Formular oder innerhalb eines Containers. Aber... wir haben eine ControlSource und anscheinend verhält sich VFP in der Art, dass zwar der Wert der Checkbox unverändert bleibt, aber trotzdem die ControlSource geändert wird und aus der Aktualisierung heraus, wechselt dann die Checkbox doch ihren Wert. Interessanterweise passiert dies nicht, wenn die Checkbox mit eigener ControlSource genutzt wird.

Da ich keine Möglichkeit gefunden habe, die Wertänderung in der Column.ControlSource zu verhindern, nutze ich die 'Technik der doppelten Negation' :icon_cool: um zum gewünschten Ergebnis zu kommen. Innerhalb des KeyPress prüfe ich auf die Existenz des Parent von der Basisklasse 'Column' und verändere den aktuellen Wert der Checkbox. Da VFP ebenfalls eine Invertierung des Value durchführt, enden wir wieder beim ursprünglichen Zustand.

Außerdem vermeiden wir das 'Drücken' der Tab-Taste, da wir ja in die nächste Spalte wechseln wollen...

Die Lösung

Und zusammengetippt sieht die KeyPress-Methode inzwischen folgendermaßen aus:

*====================================================================
* Erweiterung: Die Return/Enter-Taste soll keine Funktion besitzen.
* Das Problem ist, dass primär mit der Enter- neben der
* Tab-Taste in den Formularen und Grids navigiert wird.
*====================================================================
LPARAMETERS nKeyCode, nShiftAltCtrl

With This
  Local llColumn, lcControlSource, lcVartype, luValue
  m.llColumn = .F.
  m.lcControlSource = ""
  m.lcVartype = ""
  m.luValue = 0

  If .lSkipEnter .And. ( ;
    (m.nKeyCode == 13 .And. InList(m.nShiftAltCtrl, 0, 1)) .Or. ;
    (m.nKeyCode == 10 .And. m.nShiftAltCtrl == 2) ;
  )

    m.llColumn = (Vartype(This.Parent) == T_OBJECT .And. ;
      Lower(This.Parent.BaseClass) == "column")

    *--- Falls die Checkbox ein Child einer Column ist,
    *--- müssen wir uns um die ControlSource kümmern.
    If m.llColumn
      m.lcControlSource = This.Parent.ControlSource
      m.luValue = Evaluate(m.lcControlSource)
      m.lcVartype = Vartype(m.luValue)

      .Value = ICase( ;
        m.lcVartype == T_LOGICAL, Not m.luValue, ;
        1 - m.luValue ;
      )
    Else
      *--- Ansonsten brauchen wir den zusätzlichen TAB
      *--- nicht auszulösen.
      Keyboard '{TAB}'
    EndIf

    NoDefault
    Return
  EndIf
EndWith

DoDefault()

Der Code ist in der ersten Ableitung implementiert und durch das Setzen der Checkbox.lSkipEnter kann sowohl in Ableitungen wie auch Instanzen der Checkbox das Verhalten reguliert werden.

Interessant wie der Fuchs wieder die ganze Sache handhabt, aber okay... es ist nachvollziehbar.

Welche Tricks und Erfahrungen habt ihr mit der Checkbox bisher gemacht?


Bis denne, JoKi


blog comments powered by Disqus
 
Spacer for layout formatting