Зміна кольору осередки в stringgrid при заповненні таблиці

Зміна кольору осередки в StringGrid при заповненні таблиці

Виводжу рішення свого завдання в StringGrid. Необхідно зафарбувати якимось кольором осередку з оптимальним рішенням. Тобто в одному рядку тільки один осередок повинна бути зафарбована.

Як це реалізувати?

а як подія з натисканням клавіші зв'язати?

> А як подія з натисканням клавіші зв'язати?

Подія (OnDrawCell для StringGrid) потрібно задати в інспекторові об'єктів (перейти на вкладку "Events" і там двічі клацнути лівою кнопкою миші на відповідному подію, щоб створився обробник до нього).

А що має відбуватися при натисканні клавіші? Якщо тільки після натискання клавіші повинен оздоблюватися StringGrid, то просто створіть змінну colored = false, а в обробнику клавіші надайте їй true. А в OnDrawCell перевіряйте: якщо colored = true, то фарбуйте.

а при цьому треба використовувати StringGrid.Repaint.

procedure TForm1.StringGrid1DrawCell (Sender: TObject; ACol, ARow: Integer;
# XA0; Rect: TRect; State: TGridDrawState);
begin
# XA0; if ACol = 0 then # XA0; // зафарбовує першу осередок в рядку
# XA0; begin
# XA0; # XA0; stringGrid1.Canvas.Brush.Color: = clGray;
# XA0; # XA0; stringGrid1.Canvas.FillRect (rect);
# XA0; end;

StringGrid.Repaint ні в якому разі!

> А при цьому треба використовувати StringGrid.Repaint.

Якщо у вас раніше таблиці не оздоблювалась і тепер (наприклад, після натискання на кнопку) ви вирішили, що вона повинна почати оздоблюватися (colored = true), то напевно, не завадить викликати Refresh, інакше таблиця може перемалювати тільки коли це буде потрібно. Але після цього ні Repaint ні Refresh викликати буде не треба (особливо в OnDrawCell) - таблиця буде сама себе малювати в міру необхідності.

Чомусь закрашивается вся таблиця і тексту не видно:

procedure Tmain.stDrawCell (Sender: TObject; ACol, ARow: Integer;
# XA0; Rect: TRect; State: TGridDrawState);
begin
if coloured = true then
begin
st.Canvas.Brush.Color: = clGreen;
st.Canvas.FillRect (rect);
end;
end;

procedure Tmain.Button9Click (Sender: TObject);
var i, j: integer;
begin
coloured: = false;
for i: = 0 to st.RowCount-1 do
for j: = 0 to st.ColCount-1 do
begin
# XA0; coloured: = false;
# XA0; if (j = opt [i]) then coloured: = true;
# XA0; st.Cells [j, i]: = floattostr (reshc [i, j]) + "" + floattostr (resht [i, j]);
# XA0; st.Refresh;
end;
end;

ненарісованного тексту і не повинно бути видно

Ведмедик П'ятачок
а більш детально?

Умова, коли потрібно зафарбовувати осередок а коли немає потрібно поміщати в OnDrawCell. Ось приклад:

procedure TForm1.Button1Click (Sender: TObject);
begin
# XA0; colored: = True;
# XA0; st.Refresh;
end;

procedure TForm1.stDrawCell (Sender: TObject; ACol, ARow: Integer;
# XA0; Rect: TRect; State: TGridDrawState);
begin
# XA0; if (colored) and (ACol mod 2 = ARow mod 2)
# XA0; then st.Canvas.Brush.Color: = clWhite
# XA0; else st.Canvas.Brush.Color: = clBlack;

куди ще щось докладніше?
текст не намальований.
що має бути при цьому видно?

І. Павло
Начебто у мене так все і є крім цього умови (ACol mod 2 = ARow mod 2)

тоді він за шаховим зафарбовує

Ведмедик ХМЛ
але після натискання клавіші у мене адже таблиця заповнюється

і чого?
ти її (таблицю) не бачиш?

Ведмедик ХМЛ
бачу але осередки порожні (зелені) хоча я в них текст додаю


> Basilisk # XA0; (05.04.11 14:12) [10]
>
> Ведмедик П'ятачок
> А більш детально?

Подробиці в довідці і у викладача.

> Basilisk # XA0; (05.04.11 14:19) [14]
>
> Ведмедик ХМЛ
> Але після натискання клавіші у мене адже таблиця заповнюється

Заповнення таблиці і малювання її ж операції різні і незалежні.

> Начебто у мене так все і є крім цього умови (ACol mod
> 2 = ARow mod 2)
>
> Тоді він за шаховим зафарбовує

Замість цього умови вставте своє: "if (j = opt [i])". Зараз воно у вас в Button9Click, але має бути в stDrawCell. Спершу виконується Button9Click і встановлює colored в true. Потім, при необхідності перемальовування, виконується stDrawCell, в якому ви повинні перевірити: чи потрібно осередок прикрасити і прикрасити її.

бачу але осередки порожні (зелені) хоча я в них текст додаю

Все що ти намалював - ти бачиш.
Все чого ти не малював - ти не бачиш.
Принаймні не повинен бачити в нормальному стані свідомості.

> Осередки порожні (зелені) хоча я в них текст додаю

Ось з висновком тексту:

procedure TForm1.Button1Click (Sender: TObject);
begin
# XA0; st.Cells [1, 1]: = "aaa";
# XA0; colored: = True;
# XA0; st.Refresh;
end;

procedure TForm1.stDrawCell (Sender: TObject; ACol, ARow: Integer;
# XA0; Rect: TRect; State: TGridDrawState);
begin
# XA0; if (colored) and (ACol mod 2 = ARow mod 2)
# XA0; then st.Canvas.Brush.Color: = clWhite
# XA0; else st.Canvas.Brush.Color: = clBlack;

# XA0; st.Canvas.FillRect (Rect);
# XA0; st.Canvas.TextRect (Rect, Rect.Left, Rect.Top, st.Cells [ACol, ARow]);
end;

Навіть можна без "st.Canvas.FillRect (Rect);", тому що TextRect сам фон малює.

procedure Tmain.stDrawCell (Sender: TObject; ACol, ARow: Integer;
# XA0; Rect: TRect; State: TGridDrawState);
var i, j: integer;
begin
for i: = 0 to st.RowCount-1 do
for j: = 0 to st.ColCount-1 do
begin
if (coloured = true) and (j = opt [i]) then # XA0; st.Canvas.Brush.Color: = clGreen
else st.Canvas.Brush.Color: = clWhite;
st.Canvas.FillRect (Rect);
st.Canvas.TextRect (Rect, Rect.Left, Rect.Top, st.Cells [ACol, ARow]);
end;
end;

procedure Tmain.Button9Click (Sender: TObject);
var i, j: integer;
begin
for i: = 0 to st.RowCount-1 do
for j: = 0 to st.ColCount-1 do
begin
# XA0; st.Cells [j, i]: = floattostr (reshc [i, j]) + "" + floattostr (resht [i, j]);
# XA0; coloured: = true;
# XA0; st.Refresh;
end;

Текст видно, але осередки все одно все зафарбовує

> For i: = 0 to st.RowCount-1 do
> For j: = 0 to st.ColCount-1 do

Цей цикл в stDrawCell не потрібен. stDrawCell для кожного осередку викликається свій, при цьому координати осередку, для якої був викликаний stDrawCell можна дізнатися, прочитавши параметри ACol і ARow. Тобто всередині stDrawCell потрібно прикрашати тільки одну клітинку - з координатами [ACol; ARow]:

if (coloured = true) and (ACol = opt [i]) then # XA0; st.Canvas.Brush.Color: = clGreen
else st.Canvas.Brush.Color: = clWhite;
st.Canvas.FillRect (Rect);
st.Canvas.TextRect (Rect, Rect.Left, Rect.Top, st.Cells [ACol, ARow]);

навіщо цей дебільний подвійний цикл всередині події відтворення?

if (coloured = true) and (ACol = opt [i]) then # XA0; st.Canvas.Brush.Color: = clGreen

Всім велике спасибі))))