![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Перемещение по DrawGrid [D5, XP]
Евгений Р. © (2007-07-10 22:02:00)Как при изменении текущей ячейки (col) подсвечивать соответствующую ей ячейку в заголовочной строке другим цветом?
Евгений Р. (2007-07-13 13:22:00) [1]
> У тебя, насколько можно понять по обилию inherited, наследник
> грида, так что для твоих методом можешь считать их Public.
>
Но это не единственный dbGrid у меня.
> Код VCL разве закрыли?
Все равно спасибо!
ЮЮ (2007-07-13 12:59:00) [2]> Жалко только, что ValidateCell находится в protected.
У тебя, насколько можно понять по обилию inherited, наследник грида, так что для твоих методом можешь считать их Public.
> Чем отличаются InvalidateGrid от Invalidate от Refresh?
> Для чего нужен InvalidateEditor?
Код VCL разве закрыли?
Евгений Р. (2007-07-13 12:55:00) [3]
function tBrnGrid_main.SelectCell(ACol, ARow: Integer): Boolean;
begin
result:=inherited SelectCell(ACol, ARow);
if result then Begin
if col<>aCol then Begin
InvalidateCell(aCol,0);
InvalidateCell(Col,0);
End;
if row<>aRow then Begin
InvalidateCell(0,aRow);
InvalidateCell(0,Row);
End;
End;{if result}
end;{SelectCell}
Действительно лучше, чем в [3]. Работает чище. И теперь все доп.процедуры (типа DrawDataHeader из [10]) можно запихнуть внутрь DrawCell.
Жалко только, что ValidateCell находится в protected.
Ну и параллельно несколько вопросов:
Чем отличаются InvalidateGrid от Invalidate от Refresh?
Для чего нужен InvalidateEditor?
ЮЮ (2007-07-13 03:36:00) [4]> А будет ли приличным, если из .SelectCell вызывать DrawCell?
В любом методе "прилично" просто намекнуть, что требуется перерисовать определенную яцейку/столбец/строку/весь грид, а грид должен намек реализовать вызовом метода DrawCell, которой, наконец, вызовет OnDFrawCell. Вызывать OnDrawCell в OnSelectCell так же прилично, как рвать гланды через ж... - в принципе можно, но 1) требуется лишние телодвижения (вычисления CellRect) 2) дублируется код.
Метод "намека" - Innvalidate. Но это для всех ячеек грида. При желании можно использовать более "нацеленные" TCustomGrid-а: InvalidateCell/InvalidateRow/InvalidateCol
Евгений Р. (2007-07-12 20:14:00) [5]Вышло вот-так для строки и столбца:
procedure tBrnGrid_main.DrawDataHeader(row: integer; isSelected: boolean);
var R: TRect;
begin
r:=CellRect(0, row);
if isSelected then Begin
canvas.Font.Color:=clBlue;
canvas.brush.Color:=clBtnShadow;
End
else Begin
canvas.Font.Color:=clBlack;
canvas.brush.Color:=clBtnFace;
End;
canvas.FillRect(r);
DrawTextCenter(jDateToStrYY(DataFromRow(Row)),R);
end;
procedure tBrnGrid_main.DrawNomerHeader(col: integer; isSelected: boolean);
var R: TRect;
nm:tBrnChees_nom;
begin
if (ColtslNomShow.Count) then exit;
r:=CellRect(Col, 0);
if r.Left=0 then exit;
if isSelected then Begin
canvas.Font.Color:=clBlue;
canvas.brush.Color:=clBtnShadow;
End
else Begin
canvas.Font.Color:=clBlack;
canvas.brush.Color:=clBtnFace;
End;
canvas.FillRect(r);
nm:=tslNomShow.objects[Col-1] as tBrnChees_nom;
DrawTextCenter(str_li_ns(nm.nomer,4),R);
end;{DrawNomerHeader}
procedure tBrnGrid_main.DrawCell(Sender: TObject; ACol, ARow: Integer;Rect: TRect; State: TGridDrawState);
begin
if (aCol=0) and (aRow=0) then Begin
canvas.Font.Style:=[fsBold];
DrawTextCenter('Äàòà',Rect);
End
else if acol=0 then Begin
DrawDataHeader(aRow,row=aRow);
End
else if aRow=0 then Begin
DrawNomerHeader(aCol,col=aCol);
End
else DrawEl;
end;{DrawCell}
function tBrnGrid_main.SelectCell(ACol, ARow: Integer): Boolean;
begin
result:=inherited SelectCell(ACol, ARow);
DrawNomerHeader(aCol,true);
if colaCol then DrawNomerHeader(Col,false);
DrawDataHeader(aRow,true);
if rowaRow then DrawDataHeader(Row,false);
end;{SelectCell}
А будет ли приличным, если из .SelectCell вызывать DrawCell?
Евгений Р. (2007-07-12 19:38:00) [6]
> т.к. OnDrawCell вызовется как для ечейки, потерявшей фокус,
> так и для получившей.
Проблема была в том, что нужно перермсовать не ячейки, потерявшие и получившие фокус, а fixedRow ячейки соответствующих столбцов. Поэтому вызов и следовало делать из OnSelectCell. Тоже вызываю из OnDrawCell .
ЮЮ (2007-07-12 11:44:00) [7]> который и вызывать и на OnDrawCell и на OnSelectCell....
В этом нет смысла, т.к. OnDrawCell вызовется как для ечейки, потерявшей фокус, так и для получившей.
{RASkov} (2007-07-12 08:40:00) [8]А лучше сделать отдельный метод, который и вызывать и на OnDrawCell и на OnSelectCell....
Хотя я смотрю, что именно так вроде бы и сделано у автора (отдельным методом) и в Д5 может и нет параметра var CanSelect: Boolean....
просто вызывать его для фикс ячеек в OnDrawCell... Или tBrnGrid_main - это новый класс Грида?)
Я сейчас не помню, почему я прошлый раз сделал именно на OnSelectCell, видимо для уменьшения текста в посте :)
ЮЮ (2007-07-12 02:15:00) [9]Код рисования ячейки должен быть в обработчике OnDrawCell, а никак не в OnSelectCell. Проведи над своим гридом формой другого приложения и убедись, что всю твою раскраску и форматирование "смыло".
Поэтому ф-ция не отрабатывает при запуске, refresh и при скролинге таблицы.
Евгений Р. (2007-07-12 00:55:00) [10]Построил по принципу {RASkov} . Вместо цикла делаю вызов UpRect для значения ACol и DownRect для Col.
procedure tBrnGrid_main.DrawTextCenter(txt: string; Rect: TRect);
var x,y:integer;
Begin
y:=rect.Top;
x:=(rect.Left+rect.right) div 2 - canvas.TextWidth(txt) div 2;
canvas.TextOut(x,y,txt);
end;{DrawTextCenter}
function tBrnGrid_main.SelectCell(ACol, ARow: Integer): Boolean;
var R: TRect;
nm:tBrnChees_nom;
begin
result:=inherited SelectCell(ACol, ARow);
r:=CellRect(ACol, 0);
if (r.left>0) then Begin
canvas.Font.Color:=clBlue;
canvas.brush.Color:=clBtnShadow;
canvas.FillRect(r);
nm:=tslNomShow.objects[aCol-1] as tBrnChees_nom;
DrawTextCenter(str_li_ns(nm.nomer,4),R);
End;{if}
r:=CellRect(Col, 0);
if (Col>0) and (col<>aCol) and (r.left>0) then Begin
canvas.Font.Color:=clBlack;
canvas.brush.Color:=clBtnFace;
canvas.FillRect(r);
nm:=tslNomShow.objects[Col-1] as tBrnChees_nom;
DrawTextCenter(str_li_ns(nm.nomer,4),R);
End;{if}
end;{SelectCell}
ТОлько ф-ция не отрабатывает при запуске, refresh и при скролинге таблицы.
ЮЮ (2007-07-11 03:57:00) [11]Показывай свой OnDrawCell.
{RASkov} (2007-07-10 23:56:00) [12]> [2] Евгений Р. (10.07.07 23:52)
Там вобщето для стринггрида и не цветом а.... по другому :)
Ну думаю идея пойдет и для DrawGrida:
[2] RASkov (04.02.07 06:41)
> [0] Medved_ (03.02.07 12:32)
Со StringGrid'ом задуманное вряд ли получится, нужно что нибудь другое искать.
Но если ячейка выделена одна может быть, и не так много их(ячеек) в гриде, то можно и так попробывать:
procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);
var R: TRect;
procedure DownRect;
begin
with StringGrid1.Canvas do begin
Pen.Color:=clGray;
MoveTo(R.Left+1, R.Top+1); LineTo(R.Right-1, R.Top+1);
MoveTo(R.Left+1, R.Top+1); LineTo(R.Left+1, R.Bottom-1);
Pen.Color:=clWhite;
MoveTo(R.Right-1, R.Top+1); LineTo(R.Right-1, R.Bottom-1);
MoveTo(R.Right-1, R.Bottom-1); LineTo(R.Left+1, R.Bottom-1);
end;
end;
procedure UpRect;
begin
with StringGrid1.Canvas do begin
Pen.Color:=clWhite;
MoveTo(R.Left+1, R.Top+1); LineTo(R.Right-1, R.Top+1);
MoveTo(R.Left+1, R.Top+1); LineTo(R.Left+1, R.Bottom-1);
Pen.Color:=clGray;
MoveTo(R.Right-1, R.Top+1); LineTo(R.Right-1, R.Bottom-1);
MoveTo(R.Right-1, R.Bottom-1); LineTo(R.Left+1, R.Bottom-1);
end;
end;
var N: Integer;
begin
for N:=0 to StringGrid1.ColCount-1 do begin
R:=StringGrid1.CellRect(N, 0);
if N<>ACol then UpRect else DownRect;
end;
for N:=0 to StringGrid1.RowCount-1 do begin
R:=StringGrid1.CellRect(0, N);
if N<>ARow then UpRect else DownRect;
end;
end;
Хотя может кто и лучше, что придумает..
ЗЫ DefaultDrowing = True; Вообще все свойства StringGrid'а1 по умолчанию...
Там это был последний пост и... лучше вариантов не было. Может теперь будут :)
Евгений Р. (2007-07-10 23:52:00) [13]Спасибо, но ссылка не работает!
{RASkov} (2007-07-10 23:47:00) [14]http://www.delphimaster.ru/cgi-bin/forum.pl?n=0&id=1170495138