![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Коррекция ширины колонки в TStringGrid - не работает...
Anthony © (2012-01-16 22:44:00)Есть грид, sgTable, допустим в нём 3 ячейки, в каждом по 1 слову.
И есть список слов slBlackWord: TStringList;
Когда таблица в фокусе, по нажатию одной из функциональных клавиш, слово текущей ячейки таблицы добавляется в slBlackWord.
В таблице обрабатывается событие, позволяющие выделить слова, занесённые в "чёрный список" жирным шрифтом:
procedure sgTableDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: GridDrawState);
begin
with sgTable do begin
if slBlackWord.IndexOf(Cells[ACol, ARow]) > -1 then begin
Canvas.FillRect(Rect);
Canvas.Font.Style := [fsBold]; // слова "чёрного списка" пишем Bold - стилем
Canvas.TextOut(Rect.Left + 1, Rect.Top + 2, Cells[ACol, ARow]);
end;
end;
end;
Теперь в чём вопрос: после того как одно из слов стало "жирным", надо подкорректировать ширину столбца, в котором находится это слово.
Это делает следующий код:
procedure CorrectColumnSize(iCol: Integer);
var
i, Wid: Integer;
begin
with sgTable do begin
ColWidths[iCol] := 0;
for i := 0 to RowCount - 1 do begin // находим длину самого длинного текста в столбце iCol
Wid := Canvas.TextWidth(Cells[iCol, i] + ' ');
if Wid > ColWidths[iCol] then ColWidths[iCol] := Wid;
end;
end;
end;
И наконец тот вопрос, с которым не могу сам разобраться:
Почему после вызовы процедуры коррекции - ширина столбца меняется только для слова в самой крайней правой ячейке??
А для всех других ячеек стоящих не с краю, не работает?...
Добавлю ещё, что почему-то такой странный эффект происходит:
Если крайнее правое слово в гриде - "чёрное", то все остальные слова при переходе в BOLD - меняют ширину столбца, а при убирании с них BOLD стиля - коррекция не работает.
А вот если крайне правое слово сделать НЕ "чёрным", то все остальные слова уже не хотят корректировать ширину своих стобцов при переходе в BOLD стиль, а наоборот, при снятии жирного стиля - коррекция работает...
Чудеса прям...))
Anthony (2012-01-17 17:17:00) [1]
procedure MTabOneVerseClick(Sender: TObject);
// MTabOneVerse - элемент меню - переключатель (AutoCheck = True)
// от него зависит, станет слово "чёрным" или наоборот
var
iPos: Integer;
begin
with SGTable, slOneVerse do begin
if MTabOneVerse.Checked then Append(Cells[Col, Row])
else if Find(Cells[Col, Row], iPos) then Delete(iPos);
Refresh; // перерисовка таблицы, чтобы было видно изменения...
CorrectColumnSize(Col); // коррекция ширины текущего столбца
end;
end;
Так устраивает?...
Германн (2012-01-17 14:20:00) [2]
> И вот тогда после этого - и вызывается
> второй раз CorrectColumnSize.
И это называется "ответ по существу"?
:)
Anthony (2012-01-17 14:14:00) [3]Где вызывается?.. Да очень просто всё.
Вызывается дважды: первый раз, когда новое слово попадает в таблицу.
И второй раз, когда перемещаясь по клеткам таблицы, пользователю нужно какое-то из слов сделать "чёрным". Тогда он нажимает определённую для этого функциональную клавишу, по которой слово добавляется в "чёрный список". А процедура sgTableDrawCell - при перерисовке ячеек, проверяет - в "чёрном" списке очередное слово или нет, и если да, то перерисовывает слово этой ячейки жирным шрифтом. И вот тогда после этого - и вызывается
второй раз CorrectColumnSize.
Германн (2012-01-17 13:54:00) [4]
> Говорить лучше по существу, иначе это просто потеря времени.
> ..
>
Так всё-таки.
> Где и как вызывается CorrectColumnSize(iCol: Integer);?
>
Anthony (2012-01-17 13:13:00) [5]Зачем говорить о том чего НЕТ. Я ведь привёл код процедуры sgTableDrawCell, и там и в помине нет чего-то, что могло бы привести к перерисовке этого же объекта, то есть грида.
Говорить лучше по существу, иначе это просто потеря времени...
Dimka Maslov (2012-01-17 10:30:00) [6]
> Чтобы не бросать слова на ветер, может объясните, чего это
> я по сути не понимаю
Процедура перерисовки - это следствие изменения состояния объекта, а не повод. Если в ней начать менять состояние, может произойти такая ситуация, при которой изменения внутри процедуры перерисовки вызовут новую процедуру перерисовки. И так де тех пор, пока не возникнет страшный зверь stack overflow. Бороться с которым при неявных вызовах затруднительно.
Anthony (2012-01-17 10:08:00) [7]Чтобы не бросать слова на ветер, может объясните, чего это я по сути не понимаю?..
А то страшный зверь чё-то никак не идёт... :)
Германн (2012-01-17 01:40:00) [8]
> Я просто не понимал сути всего этого, а оказалось всё так
> просто:)
Похоже я угадал. :)
Но ты и сейчас не понимаешь сути "всего этого". Так что я не зря спросил
> Где и как вызывается CorrectColumnSize(iCol: Integer);?
А то при таком понимании ты дождешься что придёт "Страшный зверь бесконечная рекурсия"! :)
Anthony (2012-01-17 01:17:00) [9]Большое спасибо всем, кто старался помочь в этом вопросе, благодаря одной подсказке на другом форуме, этот клубок к счастью удалось распутать. Вот в чём оказалось дело:
Когда StringGrid перерисовывает таблицу, то в зависимости от текущей ячейки - "жирное" в ней слово, или нет, он постоянно меняет канву. Но канва то ОДНА для грида!.. И вот заканчивает он все перерисовки как раз на самой нижней ячейке САМОГО ПРАВОГО столбца. И какая на нём осталась канва, то такую и читает процедура коррекции ширины столбцов!!
Я просто не понимал сути всего этого, а оказалось всё так просто:)
Тогда я вставил в процедуру коррекции ширины столбца проверку на каждой строчке - "жирное" слово в текущей ячейке, или нет - и, меняя по ходу всю ту же канву - получил в результате вызова функции Canvas.TextWidth - уже ПРАВИЛЬНОЕ значение !!!
procedure CorrectColumnSize(iCol: Integer);
var
i, Wid, M: Integer;
begin
with SGTable do begin
Wid := 0;
for i := 0 to RowCount - 1 do begin
if slOneVerse.IndexOf(Cells[iCol, i]) > -1
then Canvas.Font.Style := [fsBold]
else Canvas.Font.Style := [];
M := Canvas.TextWidth(Cells[iCol, i] + ' ');
if M > Wid then Wid := M;
end;
ColWidths[iCol] := Wid;
end;
end;
Германн (2012-01-17 00:42:00) [10]
> Anthony © (17.01.12 00:16) [2]
Где и как вызывается CorrectColumnSize(iCol: Integer);?
Anthony (2012-01-17 00:16:00) [11]К сожалению не помогло... всё тот же проблем остался...
Может это какой-то глюк TStringGrid?...
И ещё у вас в коде ошибка - вместо стороки
if Wid > M then Wid := M;
нужно написать:
if M > Wid then Wid := M;
Dimka Maslov (2012-01-16 22:54:00) [12]
procedure CorrectColumnSize(iCol: Integer);
var
i, Wid, M: Integer;
begin
with sgTable do begin
Wid := 0;
for i := 0 to RowCount - 1 do begin
M := Canvas.TextWidth(Cells[iCol, i] + ' ')
if Wid > M then Wid := M;
end;
ColWidths[iCol] := Wid;
end;
end;