Skocz do zawartości

[Delphi] Kolorowanie wybranych komórek StringGrida.


olesio

Polecane posty

Witam. Siedze i kombinuje, ale nie moge sobie poradzić z jedną rzeczą. Mam na formatce standardowego StringGrida

nazwanego SG1 i taki kod jak poniżej (fragmenty). I problem polega na tym, że gdy klikne dwukrotnie w komórke SG1

to zmienia ona kolor wypełnienia oraz czcionki na żądany. Wierszy do klikania jest 13. I załóżmy, że klikne na pierwszy

oraz drugi. Jednak kiedy przyciskiem ustawię AktualnyGraczNr := 2; i kliknę w kolumnie o indeksie 2. To w poprzedniej

z kolumn kolorowe zaznaczenie zostanie tylko przy pierwszym klikniętym elemencie. Kolor z ostatniej pokolorowanej

komórki znika. To samo stanie się na przykład z pierwszą komórką jeżeli najpierw kliknę dwukrotnie na nią, a później

na przykłąd na drugą komórkę - po czym znowu na pierwszą komórkę i zmienie przyciskiem AktualnyGraczNr := 2; to

kolorowanie z pierwszej komórki zniknie. Jak temu zaradzić aby pozostawały wszystkie zawarte w zbiorze komórki

pokolorowane poprawnie? Co ciekawe jeżeli klikne na niewłaściwą kolumnę (inna niż w zmiennej AktualnyGraczNr)

i pokaże mi się komunikat z ShowMessage, to po jego zamknięciu i zmianie AktualnyGraczNr - oznaczenia zostają w

sposób prawidłowy. Kombinowałem już ze zmianą Focusa na jakiś inny element formatki, ale to nie pomogło. Może

ktoś z Was wie jak zrobić aby StringGrid zachowywał się poprawnie. Ewentualnie jakiś inny pomysł na zmiane dla

dwukrotnie klikniętej komórki koloru na stałe. Dodam, że próbowałem chyba różnych opcji StringGrida, a także je w

całości wyłączałem. Teraz mam tylko takie [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine]. Może coś

trzeba jeszcze poprawić czy przestawić, ale nie wiem. Dodam, że wolę raczej używać standardowy StringGrid..

// ... ciach...
const
 Min_Graczy = 1;
 Max_Graczy = 2;
// ... ciach ...
 public
   KoloroweTab : array[1..Max_Graczy] of set of Byte;
   AktualnyGraczNr, AktualnaKolumna, AktualnyWiersz : Byte;
//... ciach ...
procedure TMainForm.SG1DrawCell(Sender: TObject; ACol, ARow: Integer;
 Rect: TRect; State: TGridDrawState);
var
 I : Byte;
 S : string;
 DrawRect : TRect;
begin
 S := SG1.Cells[ACol, ARow];
 DrawRect := Rect;
 DrawRect.Left := DrawRect.Left + 2;
 DrawRect.Top := Drawrect.Top + 4;
 Drawrect.Right := Rect.Right;
 SG1.Canvas.FillRect(DrawRect);
 DrawText(SG1.Canvas.Handle, Pchar(S), Length(S), DrawRect, dt_Center);

 if (ACol = AktualnyGraczNr) and (ARow in KoloroweTab[AktualnyGraczNr]) then
   begin
   SG1.Canvas.Brush.Color := RGB(255, 165, 0);
   SG1.Canvas.Font.Color := clWhite;
   SG1.Canvas.FillRect(Rect);
   DrawText(SG1.Canvas.Handle, Pchar(S), Length(S), DrawRect, dt_Center);
   end;
end;
// ... ciach ...
procedure TMainForm.SG1DblClick(Sender: TObject);
begin
 if AktualnaKolumna <> AktualnyGraczNr then
   begin
   ShowMessage(Format(
      'Jesteś graczem numer: %d, a próbujesz wpisać punkty za kombinacje dla gracza numer: %d',
         [AktualnyGraczNr, AktualnaKolumna]));
   Exit;
   end;
 PlayerClicks[AktualnyGraczNr][AktualnyWiersz] := True;
 KoloroweTab[AktualnyGraczNr] := KoloroweTab[AktualnyGraczNr] + [AktualnyWiersz];
end;

Pozdrawiam: olesio

Link do komentarza
Udostępnij na innych stronach

na poczatek wyswietlilbym z boku zawartosc PlayerClicks i KoloroweTab i sprawdzal czy ma odpowiednie wartosci do wymaganego kolorowania.

Pokombinowalbym tez z wywolaniem repainta pamietam ze kiedys mialem problem z inna kontrolka bo nie bylo repainta na calym obszarze tylko na clipie. Jak nie pomoze to przeczytam dokladniej posta bo strasznie dlugi i zawily :)

Always Dark<br />u1_tt_logo.png banner-1.pngexFabula-banner.pngson_banner_ubersmall.jpg

Link do komentarza
Udostępnij na innych stronach

na poczatek wyswietlilbym z boku zawartosc PlayerClicks i KoloroweTab i sprawdzal czy ma odpowiednie wartosci do wymaganego kolorowania.

Pokombinowalbym tez z wywolaniem repainta pamietam ze kiedys mialem problem z inna kontrolka bo nie bylo repainta na calym obszarze tylko na clipie. Jak nie pomoze to przeczytam dokladniej posta bo strasznie dlugi i zawily :)

Akurat PlayerClicks działa poprawnie i jest stworzona po to aby po dwukrotnym kliknięciu na komórkę ta zapamiętała swoją

wartość i kolejnym zaznaczeniem nie można było jej zmienić. Zdarzenie OnSelectCell wygląda tak jak poniżej. Natomiast,

w skrócie napiszę co chce osiągnąć. Chce aby po dwukrotnym kliknięciu na komórkę StringGrida zmieniła ona kolor i po

zmianie kolumny do zaznaczania - ostatnio zaznaczona komórka nie traciła tego koloru. Dzieje się tak tylko wtedy kiedy

kliknę w kolumnę, w której aktualnie nie pozwalam Użytkownikowi w ogóle klikać i pokaże się komunika z ShowMessage.

procedure TMainForm.SG1SelectCell(Sender: TObject; ACol, ARow: Integer;
var CanSelect: Boolean);
var
 I : Byte;
begin
 AktualnaKolumna := ACol;
 AktualnyWiersz := ARow;

 if AktualnaKolumna = AktualnyGraczNr then
 begin
   for I := 1 to Kategorie_Ilosc do
   begin
     if PlayerClicks[AktualnyGraczNr][I] = False then
       SG1.Cells[AktualnyGraczNr, I] := '';
   end;
   if PlayerClicks[AktualnyGraczNr][AktualnyWiersz] = False then
   begin
     // Tutaj później będzie co innego, póki co kod wstawiony dla testów
     SG1.Cells[AktualnyGraczNr, ARow] := IntToStr(Random(58) + 1);
   end;
 end;
end;

Pozdrawiam: olesio

Link do komentarza
Udostępnij na innych stronach

troche sie pogubilem, zalkladam ze mam 3 komorki A, B, C. I na poczatku wszystkie sa rysowane na czarno.

 

teraz 2x klikam na komorke A - zmienia ona kolor na zielony (B,C - czarne)

zaznaczam komorke B, komorka A zostaje zielona, B,C - czarne

klikam na komorke C, komorka A staje sie czarna, B,C czarne

takie cos ?

Always Dark<br />u1_tt_logo.png banner-1.pngexFabula-banner.pngson_banner_ubersmall.jpg

Link do komentarza
Udostępnij na innych stronach

Już sobie poradziłem, dzięki podpowiedzi na 4p (o dziwo :)) . Należy stworzyć dwuwymiarową

tablicę i to w niej przechowywać kolory. A jeszcze lepiej stworzyć tablicę Canvasów, bo jak się

użyje same kolory w takiej tablicy jak poniżej to przy odświeżeniu formatki na przykład poprzez

zminimalizowanie wszystkie czcionki będą mały kolor biały (a nie czarny) - czyli taki, jaki dla ów

klikniętych dwukrotnie komórek (z pomarąńczowym tłem) przewidziałem. Oto najwazniejszy kod:

type
 TClickArray = array[1..Kategorie_Ilosc] of boolean;
// ciach ....
 public
   OznaczajKolorami : boolean;
   ColorArray : array[0..Max_Graczy, 0..Kategorie_Ilosc] of TCanvas;
   AktualnyGraczNr, AktualnaKolumna, AktualnyWiersz : Byte;
   PlayerClicks : array[1..Max_Graczy] of TClickArray;
// ciach ...
procedure TMainForm.SG1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
var
 S : string;
 DrawRect : TRect;
begin
 S := SG1.Cells[ACol, ARow];
 DrawRect := Rect;
 DrawRect.Left := DrawRect.Left + 2;
 DrawRect.Top := Drawrect.Top + 4;
 Drawrect.Right := Rect.Right;
 SG1.Canvas.Font.Color := clBlack;
 SG1.Canvas.FillRect(DrawRect);
 DrawText(SG1.Canvas.Handle, Pchar(S), Length(S), DrawRect, dt_Center);
 if (OznaczajKolorami = True) then
 begin
   SG1.Canvas.Brush.Color := ColorArray[ACol, ARow].Brush.Color;
   SG1.Canvas.Font.Color :=  ColorArray[ACol, ARow].Font.Color;
   SG1.Canvas.FillRect(Rect);
   DrawText(SG1.Canvas.Handle, Pchar(S), Length(S), DrawRect, dt_Center);
 end;
end;

procedure TMainForm.SG1SelectCell(Sender: TObject; ACol, ARow: Integer;
var CanSelect: Boolean);
var
 I : Byte;
begin
 AktualnaKolumna := ACol;
 AktualnyWiersz := ARow;

 if AktualnaKolumna = AktualnyGraczNr then
 begin
   for I := 1 to Kategorie_Ilosc do
   begin
     if PlayerClicks[AktualnyGraczNr][I] = False then
       SG1.Cells[AktualnyGraczNr, I] := '';
   end;
   if PlayerClicks[AktualnyGraczNr][AktualnyWiersz] = False then
   begin
     SG1.Cells[AktualnyGraczNr, ARow] := IntToStr(Random(58) + 1);
   end;
 end;
end;

procedure TMainForm.SG1DblClick(Sender: TObject);
begin
 if AktualnaKolumna <> AktualnyGraczNr then
 begin
   ShowMessage(Format(
   'Jesteś graczem numer: %d, a próbujesz wpisać punkty za kombinacje dla gracza numer: %d',
   [AktualnyGraczNr, AktualnaKolumna]));
   Exit;
 end;
 PlayerClicks[AktualnyGraczNr][AktualnyWiersz] := True;
 OznaczajKolorami := True;
 ColorArray[AktualnyGraczNr, AktualnyWiersz].Font.Color := clWhite;
 ColorArray[AktualnyGraczNr, AktualnyWiersz].Brush.Color := clBlue;
end;

procedure TMainForm.TworzTabliceKolorow;
var
 I, J : Byte;
begin
 for I := 0 to High(ColorArray) do
   for J := 0 to SG1.RowCount - 1 do
   begin
     ColorArray[I][J] := TCanvas.Create;
   end;

   for I := 0 to SG1.RowCount - 1 do
   begin
     ColorArray[0][I].Brush.Color := clBtnFace;
     ColorArray[0][I].Font.Color := SG1.Font.Color;
   end;

   for I := 0 to SG1.ColCount - 1 do
   begin
     ColorArray[I][0].Brush.Color := clBtnFace;
     ColorArray[I][0].Font.Color := SG1.Font.Color;
   end;

   for I := 1 to High(ColorArray) do
     for J := 1 to SG1.RowCount - 1 do
     begin
       ColorArray[I][J].Brush.Color := SG1.Color;
       ColorArray[I][J].Font.Color := SG1.Font.Color;
     end;
   end;
// ciach ...

Pozdrawiam: olesio

Link do komentarza
Udostępnij na innych stronach

Zarchiwizowany

Ten temat jest archiwizowany i nie można dodawać nowych odpowiedzi.

×
×
  • Utwórz nowe...