Zwei farbige Spalten im StringGrid



  • davon ausgegegangen, dass es sich um einen Kalender handelt in dem auf der X-Achse die Wochentage ausgegeben werden und Samstag und Sonntag die beiden letzten Spalten sind:

    if (ACol >= StringGrid1->ColCount - 2)
    

    In diesem Fall könntest Du an Anfang (zur Laufzeit) noch Spalten für z.B. KW einfügen.

    Von welchem Typ ist DateX? Warum hast Du keine Standard-TDateTime-Komponente verwendet? Falls es eine Komponente von einem Fremdanbieter ist: Ich hab's oft genug erlebt, dass bei einem Generationswechsel die Komponenten für die neue BCB-Version nicht mehr verfügbar sind, oder in einer angepaßten Version installiert werden müssen. Dies kann dazu führen, dass man ziemlich viel Streß mit dem Anpassen der Applikationen hat. Deshalb verzichte ich mittlerweile komplett auf Komponenten von Fremdanbietern...



  • DateX ist eine Klasse von mir die (lustigerweise) C-Komponenten enthaelt.
    Ich mag halt nicht alles von C++.

    Ich moechte auch nur spezielle Komponenten von der IDE uebernehmen und ansonsten traditionell meine eigenen Funktionen schreiben.



  • Böse Zungen würden vom 'Rad neu erfinden' sprechen. 😉



  • Hallo

    Fuer alle interessierten.
    Ich habe das Problem so geloest:

    void __fastcall TMain::StringGrid1DrawCell(TObject *Sender, int ACol,
          int ARow, TRect &Rect, TGridDrawState State)
    {
        int x = 0;
    
        x = DateX.get_Day();
        x -= DateX.get_SinceSunday();
    
        // Ist das Datum groesser als ACol oder kleiner
        if(x > ACol)
        {
            while(x > ACol)
                x -= 7;
        }
        else if (x < ACol)
        {
            while(x < ACol)
                x += 7;
        }
    
        // Spalten farbig zeichnen
        // Samstag
        if (ACol == x - 1 || ACol == x)
        {
            StringGrid1->Canvas->Brush->Color = 0x8fBC8F;
            StringGrid1->Canvas->Font->Color = clWhite;
        }
    
        // Zeilen  farbig zeichnen
        if (ARow == 3)
        {
            StringGrid1->Canvas->Brush->Color = clGray;
            StringGrid1->Canvas->Font->Color = clWhite;
        }
    
        // Zelle endlich zeichnen
        StringGrid1->Canvas->FillRect(Rect);
    
        // und zum Schluss den Text in die Zelle malen
        DrawText(StringGrid1->Canvas->Handle, StringGrid1->Cells[ACol][ARow].c_str(),
            -1, &Rect, DT_SINGLELINE | DT_VCENTER | 1);  // text align, 0/1/2 - Left/Center/Right
    }
    

    Manchmal ist der einfachste Weg am schwierigsten zu erkennen



  • Aber ich habe immer noch nicht herausgefunden, wozu das x gut sein soll.



  • Meinst du das X bei DateX??



  • Darkfalcon schrieb:

    int x = 0;
    
        x = DateX.get_Day();
        x -= DateX.get_SinceSunday();
    
        // Ist das Datum groesser als ACol oder kleiner
        if(x > ACol)
        {
            while(x > ACol)
                x -= 7;
        }
        else if (x < ACol)
        {
            while(x < ACol)
                x += 7;
        }
    }
    

    Dieses int x, dass Du da verwendest. Mir entgeht komplett der Sinn dieser Vorgehensweise. So wie ich das verstehe, ist x unabhängig von der ausgewählten Spalte und Zeile und deswegen frage ich mich, was Du damit bezweckst / berechnest. Ich bin halt neugierig. 🙂



  • Dazu musst du Wissen wie DrawCell arbeitet:
    Draw Cell zeichnet immer nur die Zellen die sichtbar sind.

    Beispiel: Du hast 31 Spalten aber es sind nur 12 sichtbar. Diese 12 werde gezeichnet.

    Ich muss nun herausfinden welchen Monat wir haben, mit wievielen Tagen, wann war zuletzt Sonntag und welche Zellen werden gezeichnet.

    Mit:

    int x  = 0;
    
        x  = DateX.get_Day();
        x -= DateX.get_SinceSunday();
    

    hole ich mir das aktuelle Tagesdatum und ziehe die Zeit seit Sonntag ab.
    Wenn ich z.B. den 31. habe und seit Sonntag sind 2 Tage vergangen dann habe ich den Wert 29.
    Nun weiss ich das der 29. ein Sonntag war.

    Wenn ich aber nur die Zellen 1-12 sichtbar habe nuetzt mir das wenig.
    Ich rechne einfach mit:

    if(x > ACol)
        {
            while(x > ACol)
                x -= 7;
        }
    

    so lange den Wert runter bis er in die Zelle passt.
    29 - 7 = 22 - 7 = 15 - 7 = 8 - 7 = 1.

    Jetzt habe ich beide Sonntage.



  • Das scheint alles irgendwie unsinnig.

    Du hast das Grid doch schon mit den passenden Daten gefüllt, und das ja wohl so, dass die Wochenenden immer an bestimmten Stellen (Spalten) stehen. Wozu dann das Geeier mit deiner DateX-Klasse? Werte doch einfach die Spaltennummern aus!?
    Dabei ist es genauso egal, welche oder wieviele Zellen angezeigt werden, da OnDrawCell, wie du richtig sagst, eben nur für die sichtbaren Zellen aufgerufen wird.



  • Kann ich nur dann nachvollziehen, wenn sich die Anzahl der Spalten zur Laufzeit ändern kann. Wenn nur die Anzahl der Zeilen variabel ist, die Anzahl der Spalten aber statisch, dann muss ich Jansen zustimmen: Macht nicht viel Sinn. Und damit meine ich nicht, dass mehr oder weniger Spatlten und Zeilen sichtbar sind (z.B. durch Größenänderung des Forms) oder andere Zeilen und Spalten sichbar sind (durch Scrollen). Oder hast Du eine Funktion, die die Darstellung des Grids z.B. von 'pro Spalte ein Tag' auf 'pro Zeile ein Tag' verändert? Aber dazu ist die Funktion dann nicht geeignet?!?

    Brauche mehr Input. 🙂



  • Joe_M. schrieb:

    Kann ich nur dann nachvollziehen, wenn sich die Anzahl der Spalten zur Laufzeit ändern kann.

    Selbst wenn: im DrawText() benutzt er den aktuellen Zelleninhalt, weiss also, was drinsteht und sollte somit auch wissen, welche Spalten das Wochenende "beherbergen".



  • Deswegen ja auch:

    Joe_M. schrieb:

    Aber dazu ist die Funktion dann nicht geeignet?!?



  • Es ist nur eine Teilloesung.

    Die Daten mit denen sich das StringGrid fuellt ist abhaengig vom Monat.

    Tage = Anzahl Spalten

    Die Wochenenden stehen natuerlich nicht immer in den selben Spalten da der Sonntag z.B. nicht immer der 3. ist 😉

    Dieser Algorithmus ist NUR dafuer gedacht den Samstag und den Sonntag richtig einzuordnen und zu markieren.



  • Das wäre aber auch mit deutlich weniger Aufwand zu realisieren gewesen...

    int istWochende = TDateTime('Jahr im Grid', 'Monat im Grid', ACol).DayOfWeek();
    if (istWochenende == 1 || istWochenende == 7)
    {
       // Wochenende. Yippie.
    }
    

    Grüße



  • Darkfalcon schrieb:

    Tage = Anzahl Spalten

    Na endlich mal eine konkrete Aussage! 😉

    void __fastcall TForm1::StringGrid1DrawCell(TObject *Sender, int ACol,
          int ARow, TRect &Rect, TGridDrawState State)
    {
      TDateTime date;
      try
      {
        date = (StringGrid1->Cells[ACol][ARow]);
      }
      catch (EConvertError &E)
      {
      }
      // Samstag oder Sonntag
      if (DayOfWeek(date) == 7 || DayOfWeek(date) == 1)
      {
        StringGrid1->Canvas->Brush->Color = 0x8fBC8F;
        StringGrid1->Canvas->Font->Color = clWhite;
      }
    
      ...
    }
    

    Eleganter wär's natürlich, die (Spalten)Positionen der Wochenenden schon beim Füllen des Grids z.B. in einem Integer-Array abzulegen, das dann im OnDrawCell ausgewertet wird.



  • So viel weniger Aufwand ist es ja nu auch nicht.
    Ausserdem benoetige ich DateX ja auch noch fuer andere Bereiche.
    Und es bleibt bei C.

    Dir wuerden wahrscheinlich die Haare zu Berge stehen wenn du siehst wie ich die Zeitangabe aus dem AnsiString filtere :))


Anmelden zum Antworten