Announcement

Collapse
No announcement yet.

TDBCtrlGrid / onPaintPanel / Farbe wechseln / Bug?!?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • TDBCtrlGrid / onPaintPanel / Farbe wechseln / Bug?!?

    Hi,
    <br>
    <br>ich möchte in einem tdbctrlgrid die Hintergrundfarbe einer Zeile ändern, wenn ein bestimmter Wert in der Datenbank steht.
    <br>
    <br>Nun ist mir wohl aufgefallen, das wenn ich die Farbe ändere, so wird das Ereignis OnPaintPanel ununterbrochen aufgerufen.
    <br>
    <br>Was mache ich falsch?
    <br>Ist das ein Bug?
    <br>Bsp.:
    <pre>
    procedure TForm1.DBCtrlGrid1PaintPanel(DBCtrlGrid: TDBCtrlGrid;
    Index: Integer);
    begin
    If start Then
    begin
    If adodataset1.FieldByName('bool').asBoolean and (Index = 0) Then
    dbctrlgrid.Color := clRed
    else
    dbctrlgrid.Color := clGray;
    Edit1.text := inttostr(strtoint(Edit1.text) + 1); //liegt nicht auf dem Grid sondern auf dem Form
    End;
    end;

    procedure TForm1.Button4Click(Sender: TObject);
    begin
    if start then
    start := False
    else
    start := true;
    end;
    </pre>
    <br>
    <br>Danke!
    <br>
    <br>mfg
    <br>ps

  • #2
    Hallo,

    man darf in diesem Fall nicht direkt auf die TDBCtrlGrid-Eigenschaft <b>Color</b> zurückgreifen. In der Delphi-Hilfe zu <b>OnPaintPanel</b> steht unter anderem der folgende Satz: "<i>Mit der Eigenschaft Canvas können Sie die Tafel zeichnen. Der Punkt (0,0) der Zeichenfläche entspricht der linken oberen Ecke der Tafel und der Punkt (PanelWidth,PanelHeight) der rechten unteren Ecke.</i>". Es werden die 2 Zutaten benannt, die man für das Zeichen benötigt: <br>
    1. TRect für den Bereich (Top, Left, Bottom, Right)<br>
    2. Canvas als Zeichenoberfläche

    In einem Beispiel sieht das Ergebnis dann so aus:
    <pre>
    var
    b : Boolean;

    procedure TForm1.DBCtrlGrid1PaintPanel(DBCtrlGrid: TDBCtrlGrid;
    Index: Integer);
    var
    aRect : TRect;
    begin
    with aRect do
    begin
    Top := 0;
    Left := 0;
    Bottom := DBCtrlGrid.PanelHeight;
    Right := DBCtrlGrid.PanelWidth;
    end;
    with DBCtrlGrid do
    begin
    if b then
    begin
    Canvas.Brush.Color := clRed;
    Canvas.FillRect(aRect);
    end
    else
    begin
    Canvas.Brush.Color := clGray;
    Canvas.FillRect(aRect);
    end;
    end;
    b := not b;
    end;
    </pre>
    Der Grund für diese separate Behandlung des Hintergrunds wird ebenfalls auf der gleichen Hilfeseite genannt: "<i>Die Steuerelemente werden einzeln in die Tafel eingefügt und müssen nicht mit einer Ereignisbehandlungsroutine für OnPaintPanel gezeichnet werden.</i>"

    Comment


    • #3
      Vielen Dank!
      <br>
      <br>mfg
      <br>P

      Comment


      • #4
        Hallo A.Kosch,

        das war es noch nicht ganz. Nun möchte ich eine Art Datensatzmarkierer erzeugen. Das mache ich mit Hilfe eines Panels. Aber irgend wie will das nicht funktionieren. Und wenn ich den letzten Satz richtig interpretiere darf ich das Panel nicht in der folgenden Procedure ansprechen/belegen, aber wo sonst? Das Panel hat ja kein Ereignis on Paint.
        Bsp.:
        <pre>
        procedure TfrmLadestellenstammdaten.DBCtrlGrid1PaintPanel(
        DBCtrlGrid: TDBCtrlGrid; Index: Integer);
        begin
        edit1.text := edit1.text + '###' + inttostr(DBCtrlGrid.PanelIndex) + ' - ' + IntToStr(Index);
        If DBCtrlGrid.PanelIndex = Index Then
        begin
        Panel2.Caption := '>';
        edit1.text := edit1.text + '???';
        end
        Else
        Panel2.Caption := '';
        end;
        </pre>
        <br>
        <br>Danke!
        <br>
        <br>mfg
        <br>p

        Comment


        • #5
          Hallo,
          <br>Nach vielem Lesen und Try and Error bin ich zu folgendem Ergebnis gekommen (siehe unten). Aber wieso funktioniert das? Zunächst sah es ja so aus, das wenn man eine Eigenschaft einer Komponente in einer Zeile ändert, das sich das dann auch auf alle anderen Zeilen (vorherigen Zeilen) auswirkt, obwohl dort die Komponenten in diesen Zeilen noch zuvor eine andere Eigenschaft hatten. Und nun ist alles mit einem simplen Komponete.Show gegessen?!? Wieso?
          Hat noch jemand eine bessere Idee?
          <pre>
          procedure TfrmLadestellenstammdaten.DBCtrlGrid1PaintPanel(
          DBCtrlGrid: TDBCtrlGrid; Index: Integer);
          var
          aRect : TRect;
          begin
          with aRect do
          begin
          Top := 0;
          Left := 0;
          Bottom := DBCtrlGrid.PanelHeight;
          Right := DBCtrlGrid.PanelWidth;
          end;
          If DBCtrlGrid.PanelIndex = Index Then
          begin
          Panel2.Caption := '>';
          Panel2.Show;

          dedtSort_Name.Color := clBlack;
          dedtSort_Name.Show;

          DBCtrlGrid.Canvas.Brush.Color := clRed;
          DBCtrlGrid.Canvas.FillRect(aRect);
          end
          Else
          begin
          DBCtrlGrid.Canvas.Brush.Color := clGray;
          DBCtrlGrid.Canvas.FillRect(aRect);

          Panel2.Caption := '';
          Panel2.Show;

          dedtSort_Name.Color := clGreen;
          dedtSort_Name.Show;
          end;

          If qryLadeSort.FieldByName('anmelden').asBoolean Then // if dbcbAnmelden.Checked Then so klappt es nicht!
          Begin
          dbcbAnmelden.Color := clYellow;
          dbcbAnmelden.Show;
          End
          else
          begin
          dbcbAnmelden.Color := clWhite;
          dbcbAnmelden.Show;
          end;
          end;
          </pre>
          <br>
          <br>mfg
          <br>P

          Comment


          • #6
            gleiches Problem in C++ gelöst

            Hallo zusammen,

            vielen Dank für die ausführliche Beschreibung.
            Ich hab das gleiche Problem in C++ ( CBuilder 6) gehabt und im Netz nicht einen einzigen brauchbaren Lösungsansatz gefunden.

            In zahlreichen Delphi Foren hingegen wird das Problem öfter beschrieben.
            Da sich die Syntax von C++ und Delphi stark ähnelt kann man die Lösung des Problems meiner Meinung nach in beide Richtungen von der jeweils anderen Programmiersprache ableiten.
            Aus diesem Grund möchte ich gerne meine C++ Lösung hier posten, ich hoffe es hilft jemanden mit dem gleichen Problem.
            Macht weiter so:

            Grüße Matthias


            ##################################################

            void __fastcall TForm1:BCtrlGrid1PaintPanel(TDBCtrlGrid *DBCtrlGrid,
            int Index)
            {
            // Rect erstellen um Panelausmaße zu erfassen
            TRect myRect;

            myRect.top=0;
            myRect.left=0;
            myRect.bottom=DBCtrlGrid1->PanelHeight;
            myRect.right=DBCtrlGrid1->PanelWidth;


            // Da DataSource jeweils auf den gleichen Datensatz guckt,
            // wie DBCtrlGrid1 kann man die Werte zur Laufzeit abfragen
            if (DBCtrlGrid1->DataSource->DataSet->FieldByName("kd_fahrzeug")->AsString=="Nissan")
            {
            DBCtrlGrid1->Canvas->Brush->Color=clLime;
            DBCtrlGrid1->Canvas->FillRect(myRect);
            }
            else
            {
            DBCtrlGrid1->Canvas->Brush->Color=clRed;
            DBCtrlGrid1->Canvas->FillRect(myRect);
            }
            }

            ##################################################

            Comment

            Working...
            X