Canvas.Font.Color := clWindowText;
Canvas.Brush.Color := clWindow;
Canvas.FillRect(Rect);
StrPCopy(Buf, Cells[ACol,ARow]);
DrawText(Canvas.Handle, Buf, -1, Rect, DT_SINGLELINE orDT_VCENTER orDT_NOCLIP orDT_LEFT);
end;
end;
– Jeff Fisher
Один щелчок на StringGrid вместо трех
Как сделать так, чтобы после ПЕРВОГО щелчка на ячейке возможно было бы начать редактировать ее содержимое?
Включите goAlwaysShowEditor в свойство TStringGrid Options.
– Rick Rogers
Ну это может выглядеть приблизительно так (возможно нужна некоторая доработка, написал от руки, не проверяя):
table.first;
row := 0;
grid.rowcount := table.recordCount;
while nottable.eof do begin
for i := 0 totable.fieldCount-1 do
grid.cells[i,row] := table.fields[i].asString;
inc(row);
table.next;
end;
У меня тоже имееются свои причины использования TStringGrid. Вот мой код, который загружает данные из отфильтрованной таблицы. Он не очень изящен, т.к. реально является лишь черновиком. У меня это работает, а большего мне и не нужно. Работает очень быстро, даже в случае сотни загруженных колонок. Есть много ссылок на внешние переменные. Надеюсь что они не слишком заумные.
PROCEDURE TformLookupDB.FillCells;
VAR
Row, i :INTEGER
w :INTEGER
grid :TStringGrid
BEGIN
doGrid.RowCount := 0;
IF NOTASSIGNED(fDB) THENEXIT;
Row := 0;
FORi := LOW(fColWidths) TOHIGH(fColWidths) DOfColWidths[i] := 100
// Данный временный объект-сетка используется для предохранения от огромного
// количества подразумеваемых событий Application.ProcessMessages,
// инициируемых базой данных, и вызывающих противное моргание объекта
// doGrid. Итак, мы загружаем данные в объект-сетку
// и затем копируем их в стобцы, начиная с верхней части.
grid := TStringGrid.Create(Self);
grid.Visible := FALSE;
WITHfDB DO TRY
grid.ColCount := fFields.Count;
DisableControls;
// Фильтр был установлен с помощью свойства Self.Filter
First;
WHILE NOTEOF DO TRY
grid.RowCount := Row+1;
FORi := 0 TOgrid.ColCount-1 DO BEGIN
grid.Cells[i,Row] :=FieldByName(fFields.Strings[i]).AsString
w := doGrid.Canvas.TEXTWIDTH(grid.Cells[i,Row]);
IFfColWidths[i]THENfColWidths[i] := w;
END
INC(Row);
FINALLY
Next;
END
FINALLY
doGrid.RowCount := grid.RowCount;
doGrid.ColCount := grid.ColCount;
FORi := 0 TOgrid.ColCount-1 DO BEGIN
doGrid.Cols[i] := grid.Cols[i];
doGrid.ColWidths[i] := fColWidths[i] + 4
END
grid.Free;
EnableControls
END
END;
`Авторазмер` для StringGrid
…да, реально это утомляет, но эту проблему можно решить программным путем (это нужно делать после того, как вы загрузите данные, или же, если вы загружаете данные по столбцам, их загружать в самом цикле, приведенном ниже):
i, j, temp, max: integer;
fori := 0 togrid.colcount-1 do begin
max := 0;
forj := 0 togrid.rowcount-1 do begin
temp := grid.canvas.textWidth(grid.cells[i,j]);
iftemp > max thenmax := temp;
end;
grid.colWidths[i] := max + grid.gridLineWidth +1;
end;
Вероятно, вам необходимо будет добавить +1, чтобы текст не прилипал к границам ячеек.
Выравнивание колонок StringGrid III
Вот некоторый код, который делает то, что вы хотите:
procedureWriteText(ACanvas: TCanvas; constARect: TRect; DX, DY: Integer; constText: string; Format: Word);
var
S: array[0..255] ofChar;
B, R: TRect;
begin
withACanvas, ARect do begin
caseFormat of
DT_LEFT:
ExtTextOut(Handle, Left + DX, Top + DY, ETO_OPAQUE orETO_CLIPPED,@ARect, StrPCopy(S, Text), Length(Text), nil);
DT_RIGHT:
ExtTextOut(Handle, Right - TextWidth(Text) - 3, Top + DY,ETO_OPAQUE orETO_CLIPPED, @ARect, StrPCopy(S, Text),Length(Text), nil);
DT_CENTER:
ExtTextOut(Handle, Left + (Right - Left - TextWidth(Text)) div2, Top + DY, ETO_OPAQUE orETO_CLIPPED, @ARect,StrPCopy(S, Text), Length(Text), nil);
end;
end;
end;
procedureTBEFStringGrid.DrawCell(Col, Row: Longint; Rect: TRect; State: TGridDrawState);
var
procedureDisplay( constS: string; Alignment: TAlignment);
Читать дальше