我正在尝试使用分离器来复制调整大小,就像MS {{}}中描述的MS SQL Managment Studio一样。
所以我有一个ScrollBox,它有许多面板和分离器对,彼此垂直堆叠。当我想用相应的分离器放大面板时,它会限制可能的增长到滚动框中的剩余大小。我无法将分割器拖动到滚动框的客户端大小之外。
有没有人可以帮我解决这个问题?
我试图放大滚动框的VertScrollBar.Range
,但没有成功:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;
type
tDataBlock = class(TComponent)
fPanel: TPanel;
fLabel: TLabel;
fSplitter: TSplitter;
fOwner: TWinControl;
published
property Panel: TPanel read fPanel write fPanel;
property Text: TLabel read fLabel write fLabel;
property Owner: TWinControl read fOwner write fOwner;
public
constructor Create(Owner: TWinControl; var t: integer);
end;
TForm1 = class(TForm)
ScrollBox1: TScrollBox;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
BlockCount: integer;
procedure ConfigureScreen;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.ConfigureScreen;
var i: integer;
TotalHeight: integer;
begin
TotalHeight := 0;
for I := 0 to ScrollBox1.ComponentCount - 1 do begin
if ScrollBox1.Components[i] is TPanel then
TotalHeight := TotalHeight + TPanel(ScrollBox1.Components[i]).Height;
if ScrollBox1.Components[i] is TSplitter then
TotalHeight := TotalHeight + TSplitter(ScrollBox1.Components[i]).Height;
end;
ScrollBox1.VertScrollBar.Range := TotalHeight;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
db: tDataBlock;
t: integer;
begin
t := 0;
BlockCount := 0;
for I := 0 to 3 do begin
db := tDataBlock.Create(ScrollBox1, t);
Inc(BlockCount);
end;
ConfigureScreen;
end;
{ tDataBlock }
constructor tDataBlock.Create(Owner: TWinControl; var t: integer);
begin
fOwner := Owner;
fPanel := TPanel.Create(Owner);
fPanel.Parent := Owner;
fPanel.Height := 150;
fPanel.Top := t;
fPanel.Align := alTop;
fPanel.AlignWithMargins := false;
fPanel.Color := clRed;
fPanel.ParentBackground := false;
fPanel.BorderWidth := 0;
fPanel.BorderStyle := bsNone;
fPanel.Ctl3D := false;
fPanel.AutoSize := false;
fPanel.UseDockManager := false;
t := fPanel.Top + Panel.Height + 1;
fLabel := TLabel.Create(self);
fLabel.Parent := fPanel;
fLabel.Align := altop;
fLabel.Caption := inttostr(fPanel.Height);
fLabel.Font.Size := 10;
fSplitter := TSplitter.Create(Owner);
fSplitter.Parent:= Owner;
fSplitter.Height := 3;
fsplitter.Top := t;
fSplitter.AutoSnap := false;
fSplitter.AlignWithMargins := false;
fSplitter.MinSize := 1;
fSplitter.Align := alTop;
t := fSplitter.Top + fSplitter.Height + 1;
end;
end.
答案 0 :(得分:0)
正如SilverWarior所提到的,ClientRect
的目的是划分客户区域,而不是将相邻控件调整为您想要的任何大小。为了实现您的目标,您需要通过NGLN建议的一些技巧来改变其行为。但是如果你这样做可能会遇到一些副作用,因为代码的其他部分可能需要TSplitter
的ScrollBox。
其他选项是简单地使用鼠标事件来模拟TPanel
的行为。我稍微更改了您的代码并改为使用unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls, ExtCtrls;
type
tDataBlock = class(TComponent)
private
fPanel: TPanel;
fLabel: TLabel;
fResizingPanel: TPanel;
fOwner: TWinControl;
IsResizing: Boolean;
StartHeight, StartY: Integer;
procedure ResizingPanelMouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
procedure ResizingPanelMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure ResizingPanelMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
published
property Panel: TPanel read fPanel write fPanel;
property Text: TLabel read fLabel write fLabel;
property Owner: TWinControl read fOwner write fOwner;
public
constructor Create(Owner: TWinControl; var t: Integer);
end;
TForm1 = class(TForm)
ScrollBox1: TScrollBox;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
BlockCount: Integer;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
db: tDataBlock;
t: Integer;
begin
t := 0;
BlockCount := 0;
for I := 0 to 3 do
begin
db := tDataBlock.Create(ScrollBox1, t);
Inc(BlockCount);
end;
end;
{ tDataBlock }
constructor tDataBlock.Create(Owner: TWinControl; var t: Integer);
begin
fOwner := Owner;
fPanel := TPanel.Create(Owner);
fPanel.Parent := Owner;
fPanel.Height := 150;
fPanel.Top := t;
fPanel.Align := alTop;
fPanel.AlignWithMargins := False;
fPanel.Color := clRed;
fPanel.ParentBackground := False;
fPanel.BorderWidth := 0;
fPanel.BorderStyle := bsNone;
fPanel.Ctl3D := False;
fPanel.AutoSize := False;
fPanel.UseDockManager := False;
fPanel.Constraints.MinHeight := 50;
// fPanel.DoubleBuffered := True;
t := fPanel.Top + Panel.Height + 1;
fLabel := TLabel.Create(self);
fLabel.Parent := fPanel;
fLabel.Align := alTop;
fLabel.Caption := inttostr(fPanel.Height);
fLabel.Font.Size := 10;
fResizingPanel := TPanel.Create(Owner);
fResizingPanel.Parent := Panel;
fResizingPanel.Height := 10;
fResizingPanel.Align := alBottom;
fResizingPanel.AlignWithMargins := False;
fResizingPanel.ParentBackground := False;
fResizingPanel.Cursor := crVSplit;
fResizingPanel.OnMouseDown := ResizingPanelMouseDown;
fResizingPanel.OnMouseMove := ResizingPanelMouseMove;
fResizingPanel.OnMouseUp := ResizingPanelMouseUp;
t := fResizingPanel.Top + fResizingPanel.Height + 1;
end;
procedure tDataBlock.ResizingPanelMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
IsResizing := True;
StartHeight := Panel.Height;
StartY := fResizingPanel.ClientOrigin.Y + Y;
end;
procedure tDataBlock.ResizingPanelMouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
begin
if IsResizing then
Panel.Height := StartHeight + fResizingPanel.ClientOrigin.Y + Y - StartY;
end;
procedure tDataBlock.ResizingPanelMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
IsResizing := False;
end;
end.
。但这只是一个快速入门,您可能需要更多编码,例如删除闪烁;)。
{{1}}