2

我正在编写一个面板控件,允许用户最小化面板并隐藏此面板上的组件。单个 THidePanel 似乎可以按预期工作,但是当我将其中两个放在由拆分器分隔的表单上时却没有。第一个面板对齐alLeft;第二个面板alClient

屏幕转储

单击第二个面板的按钮时,它不会对最小化或最大化做出反应。这是我所有的代码。为什么它不起作用?

const
  BoarderSize = 20;

type

TButtonPosition = (topleft, topright, buttomleft, buttomright);

///
/// a panel with a smaller panel inside  and a button on the side
///
THidePanel = class(TPanel)
private
{ Private-Deklarationen }
  ///
  /// a smaller working panel
  WorkingPanel: TPanel;
  FLargeHight: Integer;
  FLargeWidth: Integer;
  FActivateButton: TButton;
  FExpandState: Boolean;
  FButtonPosition: TButtonPosition;
  FOnActivateBtnClick: TNotifyEvent;
  procedure SetButtonPosition(const Value: TButtonPosition);
protected
{ Protected-Deklarationen }
public
{ Public-Deklarationen }
  constructor create(aOwner: TComponent); override;
  procedure WMSize(var Msg: TWMSize); message WM_SIZE;
  procedure HideComponents;
  procedure H_ActivateButtonClick(Sender: TObject);
  procedure SetState(astate: Boolean);
  procedure free;
  destructor destroy; override;
published
{ Published-Deklarationen }
  property OnActivateButtonClick: TNotifyEvent read FOnActivateBtnClick
    write FOnActivateBtnClick;
  property ButtonPosition: TButtonPosition read FButtonPosition
    write SetButtonPosition;
end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Samples', [THidePanel]);
end;

{ THidePanel }

constructor THidePanel.create(aOwner: TComponent);
begin
  inherited;
  WorkingPanel := TPanel.create(self);
  WorkingPanel.Caption := 'V01';
  FActivateButton := TButton.create(self);
  FActivateButton.Parent := self;
  FActivateButton.Caption := '<';
  FActivateButton.OnClick := H_ActivateButtonClick;
  FActivateButton.Width := BoarderSize;
  FActivateButton.Height := BoarderSize;
  WorkingPanel.Caption := '';
  FLargeWidth := self.Width;
  SetButtonPosition(topright);
end;

destructor THidePanel.destroy;
begin
  inherited;
end;

procedure THidePanel.free;
begin
  inherited;
  WorkingPanel.free;
  FActivateButton.free;
end;

procedure THidePanel.HideComponents;
var
  i: Integer;
begin
  for i := 0 to WorkingPanel.ControlCount - 1 do
    WorkingPanel.Controls[i].Visible := False;
end;

procedure THidePanel.WMSize(var Msg: TWMSize);
begin
   ///  set inner panel size
   WorkingPanel.Top := self.Top + BoarderSize;
   WorkingPanel.Left := self.Left + BoarderSize;
   WorkingPanel.Width := self.Width - 2 * BoarderSize;
   WorkingPanel.Height := self.Height - 2 * BoarderSize;

   ///  move button
  SetButtonPosition(FButtonPosition);
end;

procedure THidePanel.H_ActivateButtonClick(Sender: TObject);
begin
  /// button is clicked!
  ///
  FExpandState := not FExpandState;
  SetState( FExpandState );

  ///
  if (Assigned(FOnActivateBtnClick)) then
    FOnActivateBtnClick(self);
end;

procedure THidePanel.SetButtonPosition(const Value: TButtonPosition);
begin
  FButtonPosition := Value;

  case FButtonPosition of
    topleft:
    begin
      FActivateButton.Left := 0;
      FActivateButton.Top := 0;
    end;

  topright:
  begin
    FActivateButton.Left := self.Width - BoarderSize;
    FActivateButton.Top := 0;
  end;

  buttomleft:
  begin
    FActivateButton.Left := 0;
    FActivateButton.Top := self.ClientWidth - BoarderSize;
  end;

  buttomright:
  begin
    FActivateButton.Top := self.ClientWidth - BoarderSize;
    FActivateButton.Left := self.Width - BoarderSize;
  end;

  else
  /// never go here

  end;
end;

procedure THidePanel.SetState(astate: Boolean);
begin
  if astate then
  begin
    /// ...
    FActivateButton.Caption := '>';
    self.Width :=  BoarderSize;
  end
  else
  begin
    /// ...
    FActivateButton.Caption := '<';
   self.Width := FLargeWidth;
  end;
end;
4

2 回答 2

7

当 Control 的 Anchors 设置为alClient时,您无法更改大小。
将第二个面板对齐设置为alLeftalRight。如果您想使用此控件填写表单,请设置表单的AutoSizeTrue或在 resize it 时手动设置控件的最大大小。

于 2013-04-06T21:54:05.537 回答
0

就像MohsenB已经解释过(+1ed)一样,您不能使用Align = alClient. 但是由于您将其作为组件,我会选择Align临时更改组件的设置,而不是在设计器代码中处理此问题:即使其成为组件的一个功能,以便能够将其Align属性设置为alClient并让它在情况需要时采取相应的行动。

我认为您正在寻找以下增强功能:

unit Unit2;

interface

uses
  Messages, Classes, Controls, StdCtrls, ExtCtrls;

const
  BorderSize = 20;

type
  TButtonPosition = (bpTopLeft, bpTopRight, bpBottomLeft, bpBottomRight);

  THidePanel = class(TPanel)
  private
    FActivateButton: TButton;
    FButtonPosition: TButtonPosition;
    FExpandState: Boolean;
    FOldAlign: TAlign;
    FOldWidth: Integer;
    FOnActivateBtnClick: TNotifyEvent;
    FWorkingPanel: TPanel;
    procedure ActivateButtonClick(Sender: TObject);
    procedure SetButtonPosition(Value: TButtonPosition);
  protected
    function CanResize(var NewWidth, NewHeight: Integer): Boolean; override;
    procedure Resize; override;
  public
    constructor Create(AOwner: TComponent); override;
    procedure SetState(AState: Boolean);
  published
    property ButtonPosition: TButtonPosition read FButtonPosition
      write SetButtonPosition default bpTopRight;
    property OnActivateButtonClick: TNotifyEvent read FOnActivateBtnClick
      write FOnActivateBtnClick;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Samples', [THidePanel]);
end;

{ THidePanel }

constructor THidePanel.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FWorkingPanel := TPanel.Create(Self);
  FWorkingPanel.Caption := '';
  FWorkingPanel.SetBounds(BorderSize, BorderSize, Width - 2 * BorderSize,
    Height - 2 * BorderSize);
  FWorkingPanel.Anchors := [akLeft, akTop, akRight, akBottom];
  FWorkingPanel.Parent := Self;
  FActivateButton := TButton.Create(Self);
  FActivateButton.Caption := '<';
  FActivateButton.OnClick := ActivateButtonClick;
  FActivateButton.Width := BorderSize;
  FActivateButton.Height := BorderSize;
  FActivateButton.Parent := Self;
  SetButtonPosition(bpTopRight);
end;

procedure THidePanel.ActivateButtonClick(Sender: TObject);
begin
  FExpandState := not FExpandState;
  SetState(FExpandState);
  if Assigned(FOnActivateBtnClick) then
    FOnActivateBtnClick(Self);
end;

procedure THidePanel.SetButtonPosition(Value: TButtonPosition);
begin
  if FButtonPosition <> Value then
  begin
    FButtonPosition := Value;
    case FButtonPosition of
      bpTopLeft:
        begin
          FActivateButton.Left := 0;
          FActivateButton.Top := 0;
          FActivateButton.Anchors := [akLeft, akTop];
        end;
      bpTopRight:
        begin
          FActivateButton.Left := Width - BorderSize;
          FActivateButton.Top := 0;
          FActivateButton.Anchors := [akRight, akTop];
        end;
      bpBottomLeft:
        begin
          FActivateButton.Left := 0;
          FActivateButton.Top := ClientWidth - BorderSize;
          FActivateButton.Anchors := [akLeft, akBottom];
        end;
      bpBottomRight:
        begin
          FActivateButton.Top := ClientWidth - BorderSize;
          FActivateButton.Left := Width - BorderSize;
          FActivateButton.Anchors := [akRight, akBottom];
        end;
    end;
  end;
end;

procedure THidePanel.SetState(AState: Boolean);
begin
  if AState then
  begin
    FActivateButton.Caption := '>';
    FOldAlign := Align;
    if FOldAlign = alClient then
      Align := alLeft;
    Width :=  BorderSize;
  end
  else
  begin
    FActivateButton.Caption := '<';
    if FOldAlign = alClient then
      Align := FOldAlign
    else
      Width := FOldWidth;
  end;
end;

procedure THidePanel.Resize;
begin
  if not FExpandState then
    FOldWidth := Width;
  inherited Resize;
end;

function THidePanel.CanResize(var NewWidth, NewHeight: Integer): Boolean;
begin
  Result := inherited CanResize(NewWidth, NewHeight);
  if FExpandState then
    NewWidth := BorderSize;
end;

end.

测试代码:

unit Unit1;

interface

uses
  Controls, Forms, Unit2, ExtCtrls;

type
  TForm1 = class(TForm)
    procedure FormClick(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormClick(Sender: TObject);
begin
  with THidePanel.Create(Self) do
  begin
    Align := alLeft;
    Parent := Self;
  end;
  with TSplitter.Create(Self) do
  begin
    Left := 200;
    Parent := Self;
  end;
  with THidePanel.Create(Self) do
  begin
    Align := alClient;
    Parent := Self;
  end;
end;

end.
于 2013-04-09T21:57:34.977 回答