В firemonkey (RAD Studio 10.3) я работаю с TStringGrid, подключенным к базе данных, и хочу изменить выравнивание текста определенного столбца. Как я могу это сделать? Изменение HorzAlign в свойстве TextSettings изменяет выравнивание всех столбцов.
Я попробовал предложенное решение в эта страница и не сработало! В более новых версиях Firemonkey приведенный ниже код решения приводит к ошибке.
type TSpecificColumn = class(TColumn)
protected
function CreateCellControl: TStyledControl;override;
end;
В классе TColumn больше нет функции CreateCellControl, которую можно было бы переопределить! Это ошибка, которую я получил:
Метод CreateCellControl не найден в базовом классе.
В событиях OnDrawColumnCell
и/или OnDrawColumnHeader
вы можете использовать TTextLayout
для этой цели. Как в следующем примере, показывающем отрисовку ячеек с тремя разными выравниваниями. То же самое можно применить при рисовании заголовков:
uses
...
fmx.textlayout;
procedure TForm11.Grid1DrawColumnCell(Sender: TObject; const Canvas: TCanvas;
const Column: TColumn; const Bounds: TRectF; const Row: Integer;
const Value: TValue; const State: TGridDrawStates);
var
tl: TTextLayout;
rf: TRectF; // added
begin
tl := TTextLayoutManager.DefaultTextLayout.Create;
try
tl.BeginUpdate;
try
// added from here
rf := Bounds;
InflateRect(rf, -2, -2);
if (TGridDrawState.Selected in State) or
(TGridDrawState.Focused in State) or
(TGridDrawState.RowSelected in State)
then
Canvas.Fill.Color := TAlphaColors.LightBlue
else
Canvas.Fill.Color := TAlphaColors.White;
Canvas.FillRect(rf, 0, 0, [], 1);
// added until here
tl.TopLeft := Bounds.TopLeft;
tl.MaxSize := PointF(Column.Width, Column.Height);
tl.Font.Size := 15;
tl.Text := 'Some text'; // Value
case Column.Index of
0: tl.HorizontalAlign := TTextAlign.Leading;
1: tl.HorizontalAlign := TTextAlign.Center;
2: tl.HorizontalAlign := TTextAlign.Trailing;
end;
finally
tl.EndUpdate;
end;
tl.RenderLayout(Canvas);
finally
tl.Free;
end;
end;
TTextLayout
имеет много других полезных опций и свойств, поэтому рекомендую ознакомиться с документацией.
Для заголовка у меня тоже была эта проблема. Добавив Column.Header := '';
в событие OnDrawColumnHeader
, заголовки стали ОК. Но для ячеек, содержащих значения базы данных, я понятия не имею! Это изображение №1 и изображение №2 до и после решения проблемы с заголовком.
Извините, что здесь. Я могу продолжить расследование, если вы можете предоставить мне набор данных в памяти, привязку данных и соответствующие части файла .fmx
(чтобы убедиться, что мои настройки равны), чтобы воспроизвести проблему. Также включите свою версию обработчика событий OnDrawColumnCell()
.
Я добавил код для очистки ячейки перед новым рисованием. Я оставляю вам выбор цвета фона для различных TDrawStates
. Это должно работать нормально как для TGrid
, так и для TStringGrid
, но если нет, предоставьте тестовый пример, как указано в моем предыдущем комментарии.
Бесконечно благодарен! Ваш новый фрагмент кода сделал свое дело. Кроме того, я изменил InflateRect(rf, -2, -2);
на InflateRect(rf, 0, 0);
, чтобы полностью покрыть предыдущие значения в ячейках. кроме того, я включил AlternatingRowBackground в настройках, и мне пришлось учитывать цвета фона для альтернативных строк. В качестве решения я проверяю, является ли индекс строки нечетным или четным, и я не знаю, правильно это или глупо!
Осталась только одна проблема! Когда я дважды щелкаю ячейку и она переходит в режим редактирования, выравнивание текста возвращается к значению по умолчанию! Например, я установил выравнивание на «по центру» в событии OnDrawColumnCell
, а свойство textalignment в инспекторе объектов установлено на «ведущий». Во время выполнения выравнивание текста «по центру», но когда я дважды щелкаю ячейку и она переходит в режим редактирования, выравнивание текста возвращается к «ведущему».
На самом деле выравнивание текста не меняется, хотя может так показаться. Это выглядит так из-за внутреннего редактора, который жестко закодирован так, чтобы открываться на левой границе ячейки и покрывать всю область ячейки. Поэтому текст в редакторе отображается слева от ячейки. TStringGrid
не позволяет отображать редактор в разных позициях.
Хорошо, я понял тебя. Я очень благодарен за вашу помощь и спасибо за ваши подробные ответы.
Помимо уже идентифицированного изменения InflateRect(rf, 0, 0)
, чтобы существующие данные отображались правильно:
Изменять
tl.Text := 'Some text'; // Value line
к
tl.Text := [StringGrid name property].Cells[Column.Index,Row];
Это сработало для меня.
Спасибо за отличный ответ! Все работает чудесно, кроме одной вещи, с которой я не знаю, что с этим делать. Как я упоминал в вопросе, мой StringGrid подключен к таблице базы данных (через TBindSourceDB) для просмотра и редактирования значений. Для свойства text созданного textlayout я сделал это:
tl.Text := value.ToString;
но теперь в каждой ячейке у меня есть два текстовых значения друг на друге. Это образ. Что вы предлагаете? @Том