[英]TStringGrid with SpeedButtons
我想在每行末尾都有一個帶圖標的按鈕。
像這兒:
我試過了
procedure TMyFrame.sgrd1DrawCell(Sender: TObject; ACol,
ARow: Integer; Rect: TRect; State: TGridDrawState);
var
canvas: TCanvas;
sgrd: TStringGrid;
point: TPoint;
btn: TSpeedButton;
begin
sgrd := TStringGrid(Sender);
canvas := sgrd.Canvas;
canvas.FillRect(Rect);
if (ACol = 1) then
begin
point := Self.ScreenToClient(ClientToScreen(Rect.TopLeft));
btn := TSpeedButton.Create(sgrd);
btn.Parent := sgrd;
btn.OnClick := SpeedButton1Click;
btn.Tag := ARow;
btn.enabled:=true;
btn.visible:= true;
btn.Top := point.Y;
btn.Left := point.X;
btn.Width := 20;
btn.Height := 24;
end;
end;
但是,盡管單擊事件起作用,但按鈕看起來並不像“活動”。 沒有點擊,懸停動畫,焦點等。
假設您可能希望能夠在StringGrid內滾動並使Buttons bee與所選行相關聯,則必須為TopLeftChanged實現一個處理程序。 如果您在Stringgrid中滾動,則不會移動按鈕,而無需為此實現代碼。
procedure TForm3.SpeedButton1Click(Sender: TObject);
begin
Showmessage(TSpeedButton(Sender).Name + ' ' + IntToStr(TSpeedButton(Sender).Tag));
end;
const
C_COL = 4;
procedure TForm3.StringGrid1TopLeftChanged(Sender: TObject);
var
point: TPoint;
btn: TSpeedButton;
row: integer;
rect: TRect;
y: integer;
begin
rect := TStringGrid(Sender).CellRect(C_COL, TStringGrid(Sender).TopRow);
point := ScreenToClient(ClientToScreen(rect.TopLeft));
y := rect.Top;
for row := 0 to TStringGrid(Sender).RowCount - 1 do
begin
btn := TSpeedButton(TStringGrid(Sender).FindComponent(Format('SP%d', [row])));
if row >= TStringGrid(Sender).TopRow then
begin
btn.Top := y;
btn.Left := rect.Left;
btn.Visible := rect.Right > 0;
y := y + TStringGrid(Sender).DefaultRowHeight;
end
else
btn.Visible := false;
end;
end;
procedure TForm3.FormCreate(Sender: TObject);
var
point: TPoint;
btn: TSpeedButton;
row: integer;
rect: TRect;
y: integer;
begin
rect := StringGrid1.CellRect(C_COL, StringGrid1.TopRow);
point := ScreenToClient(ClientToScreen(rect.TopLeft));
y := rect.Top;
for row := 0 to StringGrid1.RowCount - 1 do
begin
btn := TSpeedButton.Create(StringGrid1);
btn.Name := Format('SP%d', [row]);
btn.Parent := StringGrid1;
btn.OnClick := SpeedButton1Click;
btn.tag := row;
btn.Width := StringGrid1.ColWidths[C_COL];
btn.Height := StringGrid1.DefaultRowHeight;
btn.Visible := false;
end;
StringGrid1TopLeftChanged(TStringGrid(Sender));
end;
@Tlama建議的增強版本將有必要實現插入器類,或使用自己的組件重寫ColWidthsChanged和RowHeightsChanged,以保持繪制的按鈕正確,不僅在滾動時而且在行/列大小上均正確。
//.....
type
TStringGrid=Class(Grids.TStringGrid)
procedure ColWidthsChanged; override;
procedure RowHeightsChanged; override;
End;
TForm3 = class(TForm)
StringGrid1: TStringGrid;
SpeedButton1: TSpeedButton;
procedure FormCreate(Sender: TObject);
procedure StringGrid1TopLeftChanged(Sender: TObject);
private
procedure SpeedButton1Click(Sender: TObject);
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
Form3: TForm3;
implementation
{$R *.dfm}
{ TStringGrid }
procedure TStringGrid.ColWidthsChanged;
begin
inherited;
TopLeftChanged;
end;
procedure TStringGrid.RowHeightsChanged;
begin
inherited;
TopLeftChanged;
end;
procedure TForm3.SpeedButton1Click(Sender: TObject);
begin
Showmessage(TSpeedButton(Sender).Name + ' ' + IntToStr(TSpeedButton(Sender).Tag));
end;
const
C_COL = 4;
procedure TForm3.StringGrid1TopLeftChanged(Sender: TObject);
var
point: TPoint;
btn: TSpeedButton;
row: integer;
rect: TRect;
y: integer;
begin
for row := 0 to TStringGrid(Sender).RowCount - 1 do
begin
btn := TSpeedButton(TStringGrid(Sender).FindComponent(Format('SP%d', [row])));
if row >= TStringGrid(Sender).TopRow then
begin
rect := TStringGrid(Sender).CellRect(C_COL, row);
btn.BoundsRect := rect;
btn.Visible := rect.Right > 0;
y := y + TStringGrid(Sender).DefaultRowHeight;
end
else
btn.Visible := false;
end;
end;
procedure TForm3.FormCreate(Sender: TObject);
var
point: TPoint;
btn: TSpeedButton;
row: integer;
rect: TRect;
y: integer;
begin
rect := StringGrid1.CellRect(C_COL, StringGrid1.TopRow);
point := ScreenToClient(ClientToScreen(rect.TopLeft));
y := rect.Top;
for row := 0 to StringGrid1.RowCount - 1 do
begin
btn := TSpeedButton.Create(StringGrid1);
btn.Name := Format('SP%d', [row]);
btn.Parent := StringGrid1;
btn.OnClick := SpeedButton1Click;
btn.tag := row;
btn.Visible := false;
end;
StringGrid1TopLeftChanged(TStringGrid(Sender));
end;
procedure TForm1.FormCreate(Sender: TObject);
var
Canvas: TCanvas;
Point: TPoint;
MySpeedBtn: TSpeedButton;
Row: integer;
Rect: TRect;
begin
for Row := 1 to StringGrid1.RowCount - 1 do
begin
Rect := StringGrid1.CellRect(4, Row);
point := ScreenToClient(ClientToScreen(Rect.TopLeft));
MySpeedBtn := TSpeedButton.Create(StringGrid1);
MySpeedBtn.Parent := StringGrid1;
MySpeedBtn.OnClick := SpeedButton1Click;
MySpeedBtn.Tag := Row;
MySpeedBtn.Width := 20;
MySpeedBtn.Height := StringGrid1.RowHeights[1];
MySpeedBtn.Top := Point.Y;
MySpeedBtn.Left := Point.X + StringGrid1.ColWidths[1] - MySpeedBtn.Width;
end;
end;
問題在於,每次需要刷新單元格時,您都在不斷創建新的speedbutton。 您必須在Create事件中創建按鈕。
procedure TForm1.FormCreate(Sender: TObject);
var
canvas: TCanvas;
point: TPoint;
btn: TSpeedButton;
row : integer;
rect: TRect;
begin
for row:=0 to stringGrid1.RowCount-1 do
begin
rect := stringGrid1.CellRect(1,row);
point := ScreenToClient(ClientToScreen(Rect.TopLeft));
btn := TSpeedButton.Create(StringGrid1);
btn.Parent := StringGrid1;
btn.OnClick := SpeedButton1Click;
btn.Tag := row;
btn.enabled:=true;
btn.visible:= true;
btn.Top := point.Y;
btn.Left := point.X;
btn.Width := 20;
btn.Height := 24;
end;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.