我正在尝试为TStringGrid创建一个列编辑器(显示/隐藏列)。编辑器是一个包含列表框,标签和按钮的面板。我想直接在我的TStringGrid控件中创建这个编辑器。
THE GRID:
type
TAvaGrid= class(TStringGrid;
constructor TAvaGrid.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
ColEditor:= TColEditor.Create(Self);
end;
procedure TAvaGrid.CreateWnd;
begin
inherited CreateWnd;
ColEditor.Parent := Self;
ColEditor.Visible := FALSE;
end;
编辑:
constructor TColEditor.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Self.Top := 60; { DO NOT move this in CreateWnd because controls based on this won't size properly during Create }
Self.Left := 60;
Self.Width := 220;
Self.Height := 280;
TopBar := TLabel.Create(Self);
CloseButton := TButton.Create(Self);
VisChkBox := TCheckListBox.Create(Self);
DoubleBuffered:= FALSE; { Mandatory! }
Visible := FALSE;
{ Blue caption }
TopBar.Parent := Self;
TopBar.AutoSize := FALSE;
TopBar.Height := 21;
TopBar.Align := alTop;
TopBar.Caption := ' Visible columns';
TopBar.ParentColor := FALSE;
TopBar.Transparent := FALSE;
TopBar.Cursor := crHandPoint;
TopBar.Font.Name := 'Tahoma';
TopBar.Font.Style := [System.UITypes.TFontStyle.fsBold];
TopBar.ParentFont := FALSE;
TopBar.Layout := tlCenter;
TopBar.Visible := TRUE;
TopBar.Color := TColors.Navy;
TopBar.Font.Color := TColors.White;
TopBar.OnMouseDown := TopBarMouseDown;
TopBar.OnMouseMove := TopBarMouseMove;
TopBar.OnMouseUp := TopBarMouseUp;
{ The Close button }
CloseButton.Parent := Self;
CloseButton.Width := 22;
CloseButton.Height := 20;
CloseButton.Top := 1;
CloseButton.Anchors := [akRight, akBottom];
CloseButton.Hint := 'Close';
CloseButton.Caption := 'X';
CloseButton.Visible := TRUE;
CloseButton.OnClick := CloseButtonClick;
{ The listbox }
VisChkBox.Parent := Self;
VisChkBox.AlignWithMargins:= TRUE;
VisChkBox.Align := alClient;
VisChkBox.ItemHeight := 13;
VisChkBox.Visible := TRUE;
end;
{THIS is not called until when the user presses F4 to show the 'Column Visibility' (this) panel ! }
procedure TColEditor.CreateWnd;
begin
inherited CreateWnd;
CloseButton.Left:= Self.ClientWidth- CloseButton.Width- 1;
end;
我对编辑器有刷新问题:当网格更新时(例如添加新列),编辑器会被唠叨: 我必须点击它才能使它看起来正确。
我已经尝试了WMCommand trick,但它无效。
答案 0 :(得分:2)
问题在于({1}}的油漆代码。两个控件,Panel和StringGrid,都完全在同一个相互碰撞的画布上绘制自己。对于它的价值,我没有通过使用(任意组合)覆盖及其属性设置来成功获得满意的结果。显然 - 至少可能 - 并不意味着在这种设置中使用。
但是当您从TCustomPanel
甚至TCustomControl
派生编辑器时,就没有任何绘画问题,代码就像这样:
TWinControl
我认为这是对你问题的回答。但我可以说这个解决方案远非最佳。因为编辑器控件是StringGrid的子控件,而StringGrid在使用其滚动条时在内部使用ScrollWindow
,所以编辑器的表示将被复制到全部这个地方。这是一个问题,可能还有其他问题。
解决方法是将编辑器作为子网从StringGrid中分离出来,并将其type
TColEditor = class(TWinControl)
private
FTopBar: TLabel;
FCloseButton: TButton;
FVisChkBox: TCheckListBox;
procedure CloseButtonClick(Sender: TObject);
procedure TopBarMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure TopBarMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure TopBarMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
public
constructor Create(AOwner: TComponent); override;
end;
TStringGrid = class(Grids.TStringGrid)
private
FColEditor: TColEditor;
public
constructor Create(AOwner: TComponent); override;
end;
constructor TColEditor.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
SetBounds(60, 60, 220, 280);
BevelKind := bkTile;
BevelInner := bvLowered;
BevelOuter := bvRaised;
FTopBar := TLabel.Create(Self);
FTopBar.AutoSize := False;
FTopBar.Height := 21;
FTopBar.Align := alTop;
FTopBar.Caption := ' Visible columns';
FTopBar.Transparent := False;
FTopBar.Color := TColors.Navy;
FTopBar.Cursor := crHandPoint;
FTopBar.Font.Name := 'Tahoma';
FTopBar.Font.Style := [System.UITypes.TFontStyle.fsBold];
FTopBar.Font.Color := TColors.White;
FTopBar.Layout := tlCenter;
FTopBar.OnMouseDown := TopBarMouseDown;
FTopBar.OnMouseMove := TopBarMouseMove;
FTopBar.OnMouseUp := TopBarMouseUp;
FTopBar.Parent := Self;
FCloseButton := TButton.Create(Self);
FCloseButton.SetBounds(Width - 22, 0, 22, 20);
FCloseButton.Anchors := [akTop, akRight];
FCloseButton.Hint := 'Close';
FCloseButton.Caption := 'X';
FCloseButton.OnClick := CloseButtonClick;
FCloseButton.Parent := Self;
FVisChkBox := TCheckListBox.Create(Self);
FVisChkBox.AlignWithMargins := True;
FVisChkBox.Align := alClient;
FVisChkBox.ItemHeight := 13;
FVisChkBox.Parent := Self;
end;
constructor TStringGrid.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FColEditor := TColEditor.Create(Self);
FColEditor.Parent := Self;
FColEditor.Visible := False;
end;
属性设置为StringGrid的Parent
属性。 StringGrid根本不包含子控件,设计器中的StringGrid无法接受子控件。当您将编辑器放在父母链中时,您甚至可以使用Panel解决方案。
显然,有很多其他可能的设计可用于制作可见的列选择编辑器。其中一个是使用PopupMenu,其实现可能如下所示:
Parent
答案 1 :(得分:1)
It seems to me that you are going about this the wrong way. This is not really an editor at all and should not be classed as one. Instead I think that you should put this panel into a separate form and when the user presses F4 show the form modally (creating if necessary). You will need to set the form's style, border, icons, etc. to get the appearance that you want (assuming that is important to you) but the action that you want to perform definitely screams modal form to me.