Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2012.05.20;
Скачать: CL | DM;

Вниз

Коррекция ширины колонки в TStringGrid - не работает...   Найти похожие ветки 

 
Anthony ©   (2012-01-16 22:44) [0]

Есть грид, 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 стиль, а наоборот, при снятии жирного стиля - коррекция работает...

Чудеса прям...))


 
Dimka Maslov ©   (2012-01-16 22:54) [1]

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;


 
Anthony ©   (2012-01-17 00:16) [2]

К сожалению не помогло... всё тот же проблем остался...
Может это какой-то глюк TStringGrid?...

И ещё у вас в коде ошибка - вместо стороки
if Wid > M then Wid := M;

нужно написать:
if M > Wid then Wid := M;


 
Германн ©   (2012-01-17 00:42) [3]


> Anthony ©   (17.01.12 00:16) [2]

Где и как вызывается CorrectColumnSize(iCol: Integer);?


 
Anthony ©   (2012-01-17 01:17) [4]

Большое спасибо всем, кто старался помочь в этом вопросе, благодаря одной подсказке на другом форуме, этот клубок к счастью удалось распутать. Вот в чём оказалось дело:

Когда 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 01:40) [5]


> Я просто не понимал сути всего этого, а оказалось всё так
> просто:)

Похоже я угадал. :)
Но ты и сейчас не понимаешь сути "всего этого". Так что я не зря спросил
> Где и как вызывается CorrectColumnSize(iCol: Integer);?

А то при таком понимании ты дождешься что придёт "Страшный зверь бесконечная рекурсия"! :)


 
Anthony ©   (2012-01-17 10:08) [6]

Чтобы не бросать слова на ветер, может объясните, чего это я по сути не понимаю?..

А то страшный зверь чё-то никак не идёт... :)


 
Dimka Maslov ©   (2012-01-17 10:30) [7]


> Чтобы не бросать слова на ветер, может объясните, чего это
> я по сути не понимаю


Процедура перерисовки - это следствие изменения состояния объекта, а не повод. Если в ней начать менять состояние, может произойти такая ситуация, при которой изменения внутри процедуры перерисовки вызовут новую процедуру перерисовки. И так де тех пор, пока не возникнет страшный зверь stack overflow. Бороться с которым при неявных вызовах затруднительно.


 
Anthony ©   (2012-01-17 13:13) [8]

Зачем говорить о том чего НЕТ. Я ведь привёл код процедуры sgTableDrawCell, и там и в помине нет чего-то, что могло бы привести к перерисовке этого же объекта, то есть грида.
Говорить лучше по существу, иначе это просто потеря времени...


 
Германн ©   (2012-01-17 13:54) [9]


> Говорить лучше по существу, иначе это просто потеря времени.
> ..
>

Так всё-таки.
> Где и как вызывается CorrectColumnSize(iCol: Integer);?
>


 
Anthony ©   (2012-01-17 14:14) [10]

Где вызывается?.. Да очень просто всё.
Вызывается дважды: первый раз, когда новое слово попадает в таблицу.
И второй раз, когда перемещаясь по клеткам таблицы, пользователю нужно какое-то из слов сделать "чёрным". Тогда он нажимает определённую для этого функциональную клавишу, по которой слово добавляется в "чёрный список". А процедура sgTableDrawCell - при перерисовке ячеек, проверяет - в "чёрном" списке очередное слово или нет, и если да, то перерисовывает слово этой ячейки жирным шрифтом. И вот тогда после этого - и вызывается
второй раз CorrectColumnSize.


 
Германн ©   (2012-01-17 14:20) [11]


> И вот тогда после этого - и вызывается
> второй раз CorrectColumnSize.

И это называется "ответ по существу"?
:)


 
Anthony ©   (2012-01-17 17:17) [12]

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;

Так устраивает?...



Страницы: 1 вся ветка

Текущий архив: 2012.05.20;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.008 c
15-1326056648
Dmitry1987
2012-01-09 01:04
2012.05.20
обновление данных при multi-user работе


2-1326697088
Nikitos
2012-01-16 10:58
2012.05.20
Перевод чисел из арабских в почтовый индекс


2-1326722424
Cobalt
2012-01-16 18:00
2012.05.20
TTabSet - Hint


15-1326227402
Юрий
2012-01-11 00:30
2012.05.20
С днем рождения ! 11 января 2012 среда


15-1326622195
brother
2012-01-15 14:09
2012.05.20
Продам аккаунт World Of Tanks