TCustomGrid mit DBGrid



  • Hallo,

    ich hab mal wieder iern kleines Problem:

    Ich benötige in einem DBGrid die "LeftCol"-Funtion, um bei einem Neuzeichnen des DBGrids wieder an die gleiche horizontale Position zu springen.

    Folgende Fehlermeldung kommt beim Compilieren:
    "Zugriff auf 'TCustomGrid::LeftCol' nicht möglich"

    Ich habe in der Hilfe nachgeschaut und dort steht, dass auch DBGrids Elemente von CustomGrid sind und demzufolge auch diese Funktionen genutzt werden können.

    Mit einem StringGrid funktioniert die Sache wunderbar. 🙂

    kann mir jemand helfen, wie ich diese Funktionen beim DBGrid nutzen kann?

    Danke
    Marco



  • Hallo

    wenn du diese Eigenschaft bei einem DBGrid haben willst, must du von DBGrid ableiten und diese Eigenschaft mit

    __published:
        __property LeftCol;
    

    wieder aktivieren.

    Eine Anleitung zum Erstellen eines solchen Controls findest du hier

    bis bald
    akari



  • Könntest Du das Problem ein bißchen näher erläutern. Mir ist nicht klar was Du erreichen willst. Möglicherweise gibt es deutlich einfachere und elegantere Lösungen für das Problem.



  • Also,

    Ich habe ein DBGrid, was auch wunderbar funktioniert.

    das Problem liegt darin:

    Ich habe im Event "DrawColumnCell" habe ich einige Funktionen stehen.
    Ich habe mir eine Sortierung erstellt, dass wenn ich auf die Titelleiste klicke, sich die Tabelle nach diesem Feld neu sortiert. Wenn dies der Fall ist, dann wird der "DrawColumnCell"-Event ausgelöst und das gesamte DBGrid wird neu geschrieben und meine Scrollbar steht wieder ganz links, auch wenn das Grid vorher ein ganzes Stück nach rechts gescrollt war.

    Da habe ich von der LeftCol-Funktion gehört. Im "Normalen" StringGrid funktioniert diese auch fantastisch. Nur nicht im DBGrid.

    Meine Frage nun:
    Ich möchte NACH der Aktualisierung wieder an der gleichen horizontalen Scrollposition sein, wie VORHER.

    ich denke die Antwort ist bestimmt ganz simpel, aber ihr wisst ja wie das ist mit den einfachen Sachen. Da kommt man meisst NIE drauf ...

    Gruß Marco



  • ok, in diesem Fall -> akaris Antwort... Sorry.



  • Vielleicht kannst Du Dir auch mit einer "Cracker"-Klasse helfen.
    Du schreibst Dir in Deiner Header-Datei eine Ableitung von TDBGrid, die lediglich im public-Bereich die Eigenschaft
    (ohne Typbezeichner) stehen hat.
    Immer wenn Du auf die Eigenschaft zugreifen willst, machst Du einen Cast auf Deine Cracker-Klasse und kannst somit
    die Eigenschaft nutzen.

    // Header
    class TCrackerDBGrid: public TDBGrid
    {
    public:
       __property LeftCol;
    };
    // Irgendwo in Deinem Quelltext
    ((TCrackerDBGrid*) DBGrid)->LeftCol
    

    Gruß,

    Alexander

    Edit: Cast auf Zeiger abgeändert



  • Ersteinmal Danke für die vielen Antworten...

    Ich habe die Klasse

    class TCrackerDBGrid: public TDBGrid 
    {
    public:
       __property LeftCol;
    };
    

    in meinem header deklariert => KEINE FEHLERMELDUNG beim Compilieren.
    Sobald ich aber im Quelltext mit

    Panel1->Caption = IntToStr(((TCrackerDBGrid)(GridMainView))->LeftCol);
    

    (GridMainView ist der Name meines DBGrids) auf die Eigenschaft zugreifen möchte, kommen die folgender Fehler:

    E2285 Keine Übereinstimmung für 'TCrackerDBGrid::TCrackerDBGrid(TDBGrid *)' gefunden
    E2031 Typumwandlung von 'TDBGrid *' nach 'TCrackerDBGrid' nicht zulässig

    bin für jeden Tip dankbar. Hab sowas mit Klassen-Ableiten noch nie gemacht...

    DANKE Marco



  • Hallo

    du must auf einen Pointer casten

    Panel1->Caption = IntToStr(((TCrackerDBGrid*)(GridMainView))->LeftCol);
    

    ich kann aber von diesem Weg nur abraten... dürfte meines Wissens undefiniert sein.

    bis bald
    akari



  • akari schrieb:

    du must auf einen Pointer casten

    Danke, war ein Fehler in meinem Code-Beispiel.

    akari schrieb:

    ich kann aber von diesem Weg nur abraten... dürfte meines Wissens undefiniert sein.

    Vielleicht ist Dein Wissen unvollständig 😉
    Diesen Trick hab ich mal von irgendeiner Webseite (finde sie nicht mehr). Im Prinzip passiert ja auch
    (fast) genau das gleiche, wie bei Deiner Lösung. Es wird lediglich die Sichtbarkeit der Eigenschaft verändert.
    Nur der Typecast ist etwas undurchsichtig. Vielleicht wird aber die Sichtbarkeit auch nur zur Kompilierzeit
    überprüft (wie bei den Generics in Java), dann dürfte es tatsächlich kein Problem sein.
    Ich habe sowas in eins unserer Programme eingebaut und es funktioniert einwandfrei.

    Als Zwischenlösung könnte man natürlich auch einfach die Komponente zur Laufzeit anlegen:

    TCrackerDBGrid* GridMainView = new TCrackerDBGrid(this);
    

    Hier ist noch ein anderer Weg, um private/protected Eigenschaften (und in diesem Fall auch Member-Variablen und Funktionen)
    sichtbar zu machen (Holzhammermethode).

    Gruß,

    Alexander



  • 👍 Vielen Tausend DANK an alle 👍

    Es hat mir sehr geholfen. ich hab mich für Alexander seine Lösung

    // Header
    class TCrackerDBGrid: public TDBGrid
    {
    public:
       __property LeftCol;
    };
    // Irgendwo in Deinem Quelltext
    ((TCrackerDBGrid*) DBGrid)->LeftCol
    

    entschieden. Diese Lösung funktioniert genauso, wie ich es benötige, auch wenn es vielleicht nicht die sauberste ist 😕

    Also, Danke und bis zum nächsten Mal.

    CU Marco 🙂



  • Hallo

    ich hab nicht behauptet, das es nicht funktioniert. Es ist eben nur bedenklich, eine Instanz auf enen Typ zu casten, mit dem die Instanz nicht erschaffen wurde.
    Übrigens kann man statt dem C-Style Cast auch besser noch einen reinterpret_cast nehmen.

    bis bald
    akari


Anmelden zum Antworten