4 Stimmen

<b>StringGrid mit BEARBEITUNG UND Bereichsauswahl?</b>

Frage:

Kann jemand auf einen Artikel oder Code-Beispiele verweisen, wie man SOWOHL Bearbeitung ALS AUCH Bereichsauswahl in einem TStringGrid bereitstellt?

Ja, ICH WEISS, es gibt Drittanbieter-Grids, die dies tun, aber es ist frustrierend, dass das integrierte Grid diese grundlegende Funktion nicht hat.

Hintergrund:

Es ist ziemlich normal, zu erwarten, dass man sowohl eine Zelle in einem Grid bearbeiten kann, als auch einen Bereich von Zellen auswählen kann, z.B. für eine Kopieraktion.

Wie geliefert, macht TStringGrid das nicht. Entweder / oder. Tatsächlich heißen es in den Dokumentationen über die Grid-Optionen: "Wenn goEditing in den Optionen enthalten ist, hat goRangeSelect keine Wirkung".

Es sieht jedoch so aus, als ob es trotzdem möglich ist, Bearbeitung und Bereichsauswahl in einem TStringGrid durchzuführen!!! Durch sorgfältige Verwendung der MouseDown-, MouseUp-, SelectCell- und Exit-Ereignisse können Sie durch Ein- und Ausschalten von Bearbeitungselementen zur richtigen Zeit ziemlich nah dran kommen. Aber ich habe es immer noch nicht perfekt und das gilt nur für die Mausbedienung, nicht für Tastaturänderungen.

3voto

David Punkte 13059

Ich habe für dies nicht den TStringGrid verwendet, daher kann ich keine spezifische Antwort geben. Aber gehe ich richtig in der Annahme, dass du manuell (im Code) das Bearbeiten einer Zelle starten kannst? Dieser Link deutet darauf hin, dass es möglich ist, auch wenn das Raster goEditing nicht in seinen Options enthält. (Siehe unten, um dies zu umgehen, wenn es nicht stimmt.)

Wenn dem so ist, würde ich folgendes vorschlagen:

Kombiniertes Auswahl- und Bearbeitungsverhalten

Ich finde das ist ein guter, Windows-Standard-Verhaltensansatz:

  • Lasse das Raster im Auswahlmodus, sodass Maus- und Tastaturinteraktion Zellen auswählen

  • Löse selbst das Bearbeiten einer Zelle aus, basierend auf bestimmten Kriterien (ich denke, dass du dies aufgrund dessen, was du in deinem letzten Absatz gesagt hast, bereits machst.) Es gibt übliche Wege, um die Bearbeitung auszulösen, und die folgenden Kriterien sind das, was meine Programme befolgen, wenn sie ähnliches Verhalten mit anderen Steuerelementen haben:

    • Auswahl ist normal. D.h., Klicken für Auswahl, Klicken und Ziehen für Mehrfachauswahl, Verwenden der Pfeiltasten und Umschalt- oder Steuerungstaste für Auswahl usw.

    • Eine Zelle betritt den Bearbeitungsmodus, wenn entweder:

      1. Eine Zelle ausgewählt ist und der Benutzer Enter oder F2 drückt (F2 ist die Standardtastenkombination für "Umbenennen" oder "Bearbeiten", die in einer Reihe von Programmen funktioniert)

      2. Der Benutzer auf eine Zelle "langsames Doppelklicken" - d.h., langsam doppelklickt zum Auswählen und Bearbeiten oder klickt erneut, nach einer Pause, auf eine bereits ausgewählte Zelle. Dies ahmt das Verhalten des Explorers nach, bei dem eine Datei ausgewählt ist und Sie später darauf klicken, um den Inline-Bearbeitung/Umbenennungsmodus zu betreten. Um dies zu implementieren, notiere, wann eine Zelle zuletzt geklickt (und ausgewählt) wurde. Wird erneut geklickt und liegt die Zeit über GetDoubleClickTime, dann wurde zweimal langsam geklickt und der Bearbeitungsmodus wird aktiviert. Dies ermöglicht es Ihnen, zwischen dem ersten Klicken zur Auswahl, einem Doppelklick (um eine Art Aktion durchzuführen) und einem langsamen zweiten Klick zur Bearbeitung zu unterscheiden.

        Ich überprüfe auch gerne die Mausposition, so dass, wenn ein Objekt langsam doppelgeklickt wird und es nicht zuerst ausgewählt wurde (d.h., dies wählt das Objekt aus und betritt dann den Bearbeitungsmodus) verifiziere ich, dass sich die Maus nicht sehr stark bewegt hat. Ich verwende GetSystemMetrics, um die Distanz für das Doppelklicken zu finden, und überprüfe, dass der langsame Doppelklick innerhalb dieses Felds liegt. (Weil es kein echter Doppelklick ist, überprüfe ich tatsächlich die Distanz mal 2. Mein Aktionscode ist:

        const int iMAX_MOVE_AMOUNT = ::GetSystemMetrics(SM_CYDOUBLECLK) * 2; (sorry, C++ nicht Delphi, aber sollte leicht konvertierbar sein!)

        aber ich bin mir nicht ganz sicher, ob dies zu 100% den Windows-Richtlinien entspricht. Praktisch erleben die Benutzer es jedoch so, wie sie es erwarten.)

Dadurch kannst du zu den geeigneten Zeiten zwischen Auswahl und Bearbeitung sowohl mit der Tastatur als auch mit der Maus wechseln.

Verschiedene Gedanken

Möglicherweise findest du, dass dies durch Unterklassenbildung von TStringGrid und das Erstellen eines neuen Komponenten sauberer und einfacher umzusetzen ist. Das ermöglicht es dir, dies im normalen Code zu implementieren und das eingebaute Verhalten zu überschreiben (anstatt Ereignishandler), während es für den Formcode unsichtbar bleibt. Es gibt dir auch Zugriff auf niedrigere Ebenen der Mausereignisse oder Windows-Nachrichten als nur über Ereignisse wie OnMouseDown verfügbar. Schließlich, wenn es Probleme gibt, den Editor anzuzeigen, wenn goEditing in den Options enthalten ist, ermöglicht dir dies, dieses Verhalten zu ändern. Du könntest auch eigene Ereignisse hinzufügen, wenn du möchtest, dass dein Code auf bestimmte Ereignisse reagiert, wie z.B. das Erstellen eines OnBeginEdit Ereignisses.

Eigene Komponenten zu erstellen wird normalerweise als fortgeschrittenes Delphi-Thema betrachtet, aber es ist eigentlich ziemlich einfach, wenn man weiß, wie es geht! Diese Seite hat ein paar gute Themen, die dich allgemein in das Thema einführen werden, und wenn du diesen Weg gehst und auf Probleme stößt, ist Stack Overflow natürlich ein guter Ort, um Fragen zu stellen :) Das Embarcadero Delphi » VCL » Komponenten schreiben Newsgruppen-/Forum ist auch eine ausgezeichnete Ressource, tatsächlich möglicherweise sogar besser als SO für dieses spezielle Thema.

Hoffentlich hilft das!

1voto

Superbebert Punkte 86

Ja, es ist ein alter Beitrag, aber das Problem besteht immer noch auf Delphi XE3. Um dieses Feature zu verwalten, habe ich im SelectCell-Prozedur den folgenden "Trick" verwendet: if (ARow = StringGridParam.Row) then begin StringGridParam.Options:= StringGridParam.Options + [goEditing] - [goRowSelect]; end else begin StringGridParam.Options:= StringGridParam.Options + [goRowSelect] - [goEditing]; end;

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X