Einzelne Zellen in DBGrid ReadOnly setzen



  • Ich habe folgendes Problem und keine (brauchbare) Idee für einen Lösungsansatz
    (FAQ + ForumSuche benutzt).

    Ich hab ein DBGrid mit statischen Spalten. Einige davon sind ReadOnly=False, also editierbar. Abhängig von bestimmten Werten in den einzelnen Datensätzen sollen bestimmte Zellen (Zeilen) nicht editierbar sein obwohl die Spalte an sich schon bearbeitbar ist.

    Gut, wahrscheinlich könnte ich hingehen, den aktuellen DS abfragen und dann die ganze Spalte ReadOnly setzen (ungetestete Idee). Aber das erscheint mir wenig elegant.

    Um OnDrawColumnCell mit Canvas im Schlepptau bin ich schon einige Male ringsrum geschlichen und habe es dann doch wieder zur Seite gelegt (zu viel Respekt davor). 😕



  • Hm noch keine Hilfe. 😞

    Ist meine Frage so kompliziert oder so dumm ?



  • Also ICH (was schon ein Witz an sich ist ^^) hab mal geschaut ob ich was finde...

    in der BCB Hilfe bin ich auf folgende Anleitung gestoßen:

    So verwenden Sie dynamische Felder in einer Anwendung:

    1 Fügen Sie Datenmengen und Datenquellen in ein Datenmodul ein.
    2 Verbinden Sie die Datenmengen mit Daten. Hierzu verwenden Sie eine Verbindungskomponente oder einen Provider, um die Quelle der Daten mit der Datenmenge zu verbinden, und legen dann die Eigenschaften fest, die angeben, welche Daten die Datenmenge repräsentiert.
    3 Ordnen Sie die Datenquellen den Datenmengen zu.
    4 Plazieren Sie datensensitive Steuerelemente in den Formularen der Anwendung, fügen Sie in alle Formular-Units den Header des Datenmoduls ein und verknüpfen Sie die datensensitiven Steuerelemente mit einer Datenquelle im Modul. Verknüpfen Sie außerdem mit jedem datensensitiven Steuerelement ein Feld, wenn das Steuerelement dies erfordert. Beachten Sie, daß beim Einsatz dynamischer Feldkomponenten nicht gewährleistet ist, daß von Ihnen angegebene Feldnamen beim Öffnen der Datenmenge dort aufscheinen.

    5 Öffnen Sie die Datenmengen.

    😃 Schonmal ganz nett wa? Besonders Schritt 4. Aber zum Glück sagt Borland folgendes im nächsten Satz:

    Dynamische Felder sind zwar einfach einzusetzen, weisen aber auch Einschränkungen auf...

    najoar jetzt beim 3. Mal lesen find ich's doch nicht so schlecht...

    EDIT: ich lebe jetzt zwar schon ca. 23 Jahre in Deutschland (also seit meiner Geburt), aber zu mir hat noch nie jemand gesagt "guck ma, da 'scheint was auf'" (to appear)



  • @Oklino.

    Den Text kenn ich. Ja das Deutsch hat was (einen leicht gestörten Ausdruck). Nur: Was hat das mit meiner Frage zu tun? 😕

    Ein Lösungsweg leitet sich daraus nicht für mich ab. Scheint heute nicht mein hellster Tag zu sein. 🤡



  • caspar_louis schrieb:

    @Oklino.

    Den Text kenn ich. Ja das Deutsch hat was (einen leicht gestörten Ausdruck). Nur: Was hat das mit meiner Frage zu tun? 😕

    eigentlich wollte ich mit meinem Beitrag sagen, dass ich in der meiner Meinung nach überbewerteten BCB Hilfe - die mit sicherheit gleich jemand empfielt - nur das da oben finde.
    Auf gut Deutsch ich hab keinen Plan von dem Kram.

    Aber mal ne Frage an dich: Fields ist ja eine Eigenschaft der DBGrid Komponente... und man kann ein bestimmtes Feld in einer Spalte auch ansprechen haben ja den index 0- größe des DS. Nun hat das Field nicht auch die Eigenschaft ReadOnly wie die Spalte?

    ...->Fields[2]->ReadOnly=true;



  • Hallo

    Du könntest im Event OnDataChange der dem DBGrid zugehörigen DataSource ja eben diese Überprüfung auf den nicht editierbaren Wert des betreffenden Feldes im aktuell ausgewählten Datensatzen machen.
    Dann kannst du passend zum Wert den Wert ReadOnly des betreffenden Feldes setzen.

    bis bald
    akari



  • @akari

    Ja könnte ich. Habe ich auch schon überlegt und ausgeschlossen.
    Ich will es gar nicht erst zu einem Änderungsversuch kommen lassen, d.h. das Feld von vorherein nicht editierbar gestalten.

    if (ADOQuery5->Active) {
       if (ADOQuery5->RecordCount > 0) {
          AnsiString asVgl = ADOQuery5->FieldValues["MITARBEITER"];
          if (asVgl==<<VERGLEICH>>) {
             DBGrid2->Columns->Items[3]->ReadOnly=true;
             DBGrid2->Columns->Items[4]->ReadOnly=true;
          }
          else {
             DBGrid2->Columns->Items[3]->ReadOnly=false;
             DBGrid2->Columns->Items[4]->ReadOnly=false;
          }
       }
    }
    

    So geht's auch (Z.B. in einem AfterScroll). Es funktioniert. Aber es ist nicht sonderlich schick.
    Ist natürlich nur schnell als Bsp. zusammenkopiert.

    ...Fields... schaue ich mir mal an.



  • Hallo

    Nur so am Rande : Das OnDataChange-Event tritt sofort auf nachdem ein Datensatz irgendwie im DBGrid ausgewählt wird. Erst danach könnte der User den Wert in einem Feld editieren, wenn es die Überprüfung in OnDataChange erlaubt.
    Und egal wie der User etwas in dem Grid editieren möchte, er muß den Datensatz vorher auswählen.
    Damit ist das mit dem Event eine sichere Sache.

    bis bald
    akari



  • akari schrieb:

    Hallo

    Nur so am Rande : Das OnDataChange-Event tritt sofort auf nachdem ein Datensatz irgendwie im DBGrid ausgewählt wird. Erst danach könnte der User den Wert in einem Feld editieren, wenn es die Überprüfung in OnDataChange erlaubt.
    Und egal wie der User etwas in dem Grid editieren möchte, er muß den Datensatz vorher auswählen.
    Damit ist das mit dem Event eine sichere Sache.

    bis bald
    akari

    Interessante Sache welche. Das habe ich immer anders empfunden. Damit habe ich bei DataSource ein Event, das ziemlich gleich reagiert (Zeitpunkt), wie AfterScroll der Query (also des DataSets). Auch das wird ja immer direkt nach Datensatzauswahl ausgeführt.

    Die Prüfung ist simpel. Die Frage - "Wie kann ich eine Zeile / Zelle uneditierbar machen?" - ist eher rethorisch. Das Ergebnis ist gegeben. Aber interessieren würde es mich schon noch, falls es da noch eine richtig schicke Lösung gibt, die sich wirklich bloß auf die DBGrid-Zelle/Zeile bezieht.



  • hmm hallo nochmal...

    ne Frage an akari...

    ist es möglich den aufbau des Grid zu steueren? also zu sagen baue eine zeile auf, dann noch eine usw. also nicht dass das grid sofort komplett gefüllt wird? Is nur gerade wieder so ein Gedankengewusel von mir. Dachte vielleicht lässt sich mit OnDrawCell ein event auslösen, wo man dann das Kriterium für das ReadOnly des Fields auswerten kann...



  • Hallo

    @ Oklino : Verstehe deine Frage nicht wirklich. Das Grid wird automatisch mit den Daten aus der Datenquelle gefüllt, und zwar entweder alle Felder oder eben die Felder die extra angelegt werden.

    OnDrawCell könnte auch gehen, wenn du noch entsprechend den übergebenen State auf gdSelected überprüfst.

    bis bald
    akari



  • BCB-Hilfe

    Durch Einstellen von DefaultDrawing auf true kann das datensensitive Gitter die Daten in den Zellen automatisch anzeigen. Durch Einstellen der Eigenschaft auf false können Sie die Standardanzeige deaktivieren, wenn in einer Ereignisbehandlungsroutine für OnDrawColumnCell oder OnDrawDataCell eine benutzerdefinierte Anzeigeroutine bereitgestellt wird. ...

    Mit einer Ereignisbehandlungsroutine für OnDrawColumnCell können Sie eine benutzerdefinierte Anzeigeroutine für die Daten in den Gitterzellen bereitstellen. Die Darstellung in der Zelle erfolgt mit den Methoden der Eigenschaft Canvas.

    ... aber das traue ich mich nicht so richtig auszuprobieren, ohne dafür mal etwas Code gesehen zu haben.



  • Hallo

    @ caspar_louis : Was gibt es da nicht zu trauen? Du kannst ja wenn du nicht sicher bist vorher ein Backup deines Projektes machen...
    Deweiteren gibt es hier im Forum schon viele Threads zu den OnDraw...-Events.

    ansonsten ist Programmieren vielleicht nichts für dich, wenn du Angst vor selber ausprobieren hast.

    bis bald
    akari



  • Hi Akari.
    Ich programmiere nicht zu meinem Vergrügen. Das bedeutet, ich muß in einem (meist sehr, sehr engen) Zeitraum im Unternehmen umsetztbare Ergebnisse vorweisen. Zeit für umfangreiche Test-Phasen habe ich da nicht. ... und zu Hause will dann nicht unbedingt weiterarbeiten.


Anmelden zum Antworten