Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi:滑动(动画)面板_Delphi_Animation_Panel_Sliding - Fatal编程技术网

Delphi:滑动(动画)面板

Delphi:滑动(动画)面板,delphi,animation,panel,sliding,Delphi,Animation,Panel,Sliding,Delphi是否有滑动(动画)面板组件 例如,它可以在(带有“热点”或隐藏/显示按钮的左侧面板)中找到 我需要的不是一个可调整大小的面板,而是一个可以从左到右水平平滑滑动的面板,它有一个隐藏/显示按钮(如果没有该按钮,这没什么大不了的) 谢谢 我们最终建立了自己的控制权。我们找不到任何我们想要的东西。结果没那么难。我确信有些情况我们没有正确处理,但这对我们来说是有益的 下面的代码使用的是cxGroupBox,因为我们需要这种外观来匹配应用程序的其余部分。对于普通的分组框,可以将其切换为非分组框

Delphi是否有滑动(动画)面板组件

例如,它可以在(带有“热点”或隐藏/显示按钮的左侧面板)中找到

我需要的不是一个可调整大小的面板,而是一个可以从左到右水平平滑滑动的面板,它有一个隐藏/显示按钮(如果没有该按钮,这没什么大不了的)


谢谢

我们最终建立了自己的控制权。我们找不到任何我们想要的东西。结果没那么难。我确信有些情况我们没有正确处理,但这对我们来说是有益的

下面的代码使用的是cxGroupBox,因为我们需要这种外观来匹配应用程序的其余部分。对于普通的分组框,可以将其切换为非分组框

我们在两个地方使用它。在一个例子中,我们在一个标准的DelphiFlow面板中有许多这样的面板(我不确定添加了什么版本)。当我们的DynPanel崩溃时,所有东西都会自动向上移动并填满空间

在另一种情况下,我们有一个窗口,它被划分为一个主要部分和一个工具箱。这两个被一个标准的分离器隔开。主窗口设置为与客户端对齐。当我们的面板塌陷或膨胀时。拆分器会自动移动并展开主节

我们从来没有让“container”控件工作得很好,这样您添加到面板的项目就可以移动到组框中通常期望的范围之外。但这并没有给我们带来任何重大问题,所以我们就离开了。这也不考虑DPI相对于按钮大小的变化。标题会变大,但按钮不会变大


unit DynPanel;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, cxGroupBox;

const
  DEFAULTBUTTONWIDTH = 16;
  DEFAULTWIDTH  = 161;
  DEFAULTHEIGHT = 81;
  cButtonPadding = 8;
  cCollapsePadding = 3;
  cCaptionPadding = '       ';
  cCollapsedSize = DEFAULTBUTTONWIDTH + cCollapsePadding;
  cAutoCollapseSize = DEFAULTBUTTONWIDTH + cButtonPadding;

type
  TCollapseDirection = (cdUp, cdRight, cdLeft);

  TMinDemension = cAutoCollapseSize..High(Integer);

  TDynPanel = class(TPanel)
  private
    FGroupBox: TcxGroupBox;
    FButtonPanel: TPanel;
    FButtonImage: TImage;

    FExpand: Boolean;
    FOldHeight: Integer;
    FOldWidth: Integer;
    FCollapseDirection: TCollapseDirection;
    FOrigGroupBoxCaption: String;
    FAutoCollapseHeight: TMinDemension;
    FAutoCollapseWidth: TMinDemension;

    FButtonPadding: integer;
    FCollapsePadding: integer;
    FCollapsedSize: integer;

    procedure SetExpand(Value: Boolean);
    procedure SetGroupBoxCaption(Value: string);
    procedure ButtonMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure CMShowingChanged(var Message: TMessage); message CM_SHOWINGCHANGED;
    procedure EnableControls(Value: Boolean);
    procedure SetCollapseDirection(Value: TCollapseDirection);
    procedure ConfigurePanel;
    procedure SetMinHeight(Value: TMinDemension);
    procedure SetMinWidth(Value: TMinDemension);
    procedure UpdateImage();

  protected
    procedure Resize; override;
    procedure ChangeScale(M, D: Integer); override;
  public
    constructor Create(AOwner: TComponent); override;
    property OldHeight: Integer read FOldHeight write FOldHeight;
    property OldWidth: Integer read FOldWidth write FOldWidth;
    property GroupBox: TcxGroupBox read FGroupBox;
  published
    property Caption: string read FOrigGroupBoxCaption write SetGroupBoxCaption;
    property Expand: Boolean read FExpand write SetExpand;
    property BevelOuter default bvNone;
    property CollapseDirection: TCollapseDirection read FCollapseDirection write SetCollapseDirection default cdUp;
    property AutoCollapseHeight: TMinDemension read FAutoCollapseHeight write SetMinHeight default cAutoCollapseSize;
    property AutoCollapseWidth: TMinDemension read FAutoCollapseWidth write SetMinWidth default cAutoCollapseSize;
  end;

procedure Register;

implementation

{$R 'ButtonImages\ButtonImages.res' 'ButtonImages\ButtonImages.rc'}

uses cxEdit;

procedure Register;
begin
  RegisterComponents('AgWare', [TDynPanel]);
end;


{ TDynPanel }

{
  TDynPanel.Create
  ---------------------------------------------------------------------------
}
constructor TDynPanel.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  Self.ControlStyle := ControlStyle - [csSetCaption];

  Self.Width := DEFAULTWIDTH;
  Self.Height := DEFAULTHEIGHT;
  BevelOuter := bvNone;

  FExpand := True;
  FOldHeight := Self.Height;
  FOldWidth := Self.Width;
  FOrigGroupBoxCaption := 'AgDynPanel';
  FCollapseDirection := cdUp;
  FAutoCollapseHeight := cAutoCollapseSize;
  FAutoCollapseWidth := cAutoCollapseSize;

  FGroupBox := TcxGroupBox.Create(Self);
  FGroupBox.Parent := Self;
  FGroupBox.Align := alClient;
  FGroupBox.Alignment := alTopLeft;

  FButtonPanel := TPanel.Create(Self);
  FButtonPanel.Parent := Self;
  FButtonPanel.Top := 0;
  FButtonPanel.Width := DEFAULTBUTTONWIDTH;
  FButtonPanel.Height := DEFAULTBUTTONWIDTH;
  FButtonPanel.Left := Width - DEFAULTBUTTONWIDTH - FButtonPadding;
  FButtonPanel.OnMouseDown := ButtonMouseDown;

  FButtonImage := TImage.Create(Self);
  FButtonImage.Parent := FButtonPanel;
  FButtonImage.Align := alClient;
  FButtonImage.Stretch := false;
  FButtonImage.Center := true;
  FButtonImage.OnMouseDown := ButtonMouseDown;

  UpdateImage;

  // The click should also work for the entire top of the group box.
  FGroupBox.OnMouseDown := ButtonMouseDown;

  FGroupBox.Caption := FOrigGroupBoxCaption;
  FGroupBox.Style.Font.Style := FGroupBox.Style.Font.Style + [fsBold];

  FButtonPadding := cButtonPadding;
  FCollapsePadding := cCollapsePadding;
  FCollapsedSize := cCollapsedSize;

end;

{
  TDynPanel.SetGroupBoxCaption
  ---------------------------------------------------------------------------
}
procedure TDynPanel.SetGroupBoxCaption(Value: String);
begin
  FOrigGroupBoxCaption := Value;
  ConfigurePanel;
end;

{
  TDynPanel.SetMinHeight
  ---------------------------------------------------------------------------
}
procedure TDynPanel.SetMinHeight(Value: TMinDemension);
begin
  if Value = FAutoCollapseHeight then
    Exit; // >>----->

  FAutoCollapseHeight := Value;

  if Showing then
    Resize;
end;

{
  TDynPanel.SetMinWidth
  ---------------------------------------------------------------------------
}
procedure TDynPanel.SetMinWidth(Value: TMinDemension);
begin
  if Value = FAutoCollapseWidth then
    Exit; // >>----->

  FAutoCollapseWidth := Value;

  if Showing then
    Resize;
end;

{
  TDynPanel.ButtonMouseDown
  ---------------------------------------------------------------------------
}
procedure TDynPanel.ButtonMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if Button  mbLeft then
    Exit; // >>----->

  if ((FExpand = True) and (Y  FCollapsePadding)) or
     ((FExpand = False) and (FCollapseDirection = cdLeft) and (X >----->

  FExpand := Value;

  //ConfigurePanel;

  //--------------------------------------------------------------------------
  // Set the group box size
  //--------------------------------------------------------------------------
  //
  // I chose to do the resizing of the control here rather than in
  // ConfigurePanel because if you do it there the SetBounds will call ReSize
  // which will call ConfigurePanel again so that you would need to keep track
  // of a boolean variable to determine if you are making recursive calls into
  // ConfigurePanel. That is one reason. Another is that when the dfm values
  // are streamed in and the properties get set you will resize the control
  // before the actual Height and Width properties are set. This will cause
  // bogus default values to be stored for FOldHeight and FOldWidth and when
  // the control is displayed the dimensions will be wrong. If you size the
  // control here then, on creation, Resize will not get called and the
  // FOldHeight and FOldWidth values will not get saved off until
  // CMShowingChanged will explicitly call ReSize after the dimensions are
  // properly set. If you move this code into ConfigurePanel then when the
  // caption is streamed in and set from the dfm then ConfigurePanel would get
  // called, we would SetBounds there and then Resize would fire storing off the
  // default invalid values for the FOld variables as mentioned above.
  // Hope this makes sense. Leave the SetBounds calls here and make your life
  // easier. :)
  //--------------------------------------------------------------------------

  // Changing to Expanded
  if FExpand = True then
  begin
    // Up
    if FCollapseDirection = cdUp then
      SetBounds(Left, Top, Width, FOldHeight)
    // Right
    else if FCollapseDirection = cdRight then
      SetBounds((Left + Width) - FOldWidth, Top, FOldWidth, Height)
    // Left
    else if FCollapseDirection = cdLeft then
      SetBounds(Left, Top, FOldWidth, Height);
  end
  // Changing to Collapsed
  else
  begin
    // Up
    if FCollapseDirection = cdUp then
    begin
      // Reset the AutoCollapseHeight just to make sure we don't try to
      // recollapse on resize.
      if FAutoCollapseHeight  FGroupBox) and
       (Self.Controls[i]  FButtonPanel) then
    begin
      Self.Controls[i].Enabled := Value;
      Self.Controls[i].Visible := Value;
    end;
  end;
end;

{
  TDynPanel.CMShowingChanged
  ---------------------------------------------------------------------------
}
procedure TDynPanel.CMShowingChanged(var Message: TMessage);
begin
  inherited;
  if Showing then
    Resize;
end;

{
  TDynPanel.Resize
  ---------------------------------------------------------------------------
}
procedure TDynPanel.Resize;
begin

  if FExpand = True then
  begin
    if (FCollapseDirection = cdUp) and (Height  FAutoCollapseHeight then
      begin
        FOldHeight := Height;
        Expand := True;
      end
      else
        Height := FCollapsedSize;
    end
    else if (FCollapseDirection = cdLeft) or (FCollapseDirection = cdRight) then
    begin
      if (Width > FAutoCollapseWidth) then
      begin
        FOldWidth := Width;
        Expand := True;
      end
      else
        Width := FCollapsedSize;
    end;
  end;

  ConfigurePanel;

end;


{
  TDynPanel.ChangeScale
  ---------------------------------------------------------------------------
}
procedure TDynPanel.ChangeScale(M, D: Integer);
begin

  FAutoCollapseHeight := MulDiv(FAutoCollapseHeight, M, D);
  FAutoCollapseWidth := MulDiv(FAutoCollapseWidth, M, D);

  FButtonPadding := MulDiv(FButtonPadding, M, D);
  FCollapsePadding := MulDiv(FCollapsePadding, M, D);
  FCollapsedSize := MulDiv(FCollapsedSize, M, D);


  FOldHeight := MulDiv(FOldHeight, M, D);
  FOldWidth := MulDiv(FOldWidth, M, D);

  // inherited will cause resize to be called.  I need to update
  // my internal values before that happens, otherwise I will resize based
  // on the old values.
  inherited;

end;

{
  TDynPanel.SetCollapseDirection
  ---------------------------------------------------------------------------
}
procedure TDynPanel.SetCollapseDirection(Value: TCollapseDirection);
begin
  if Value = FCollapseDirection then
    Exit; // >>----->

  FCollapseDirection := Value;

  ConfigurePanel;
end;

{
  TDynPanel.ConfigurePanel
  ---------------------------------------------------------------------------
}
procedure TDynPanel.ConfigurePanel;
begin
  //--------------------------------------------------------------------------
  // Set the group box style, caption alignment, caption, button position, and
  // button image
  //--------------------------------------------------------------------------

  // Changing to Expanded
  if FExpand = True then
  begin
    FGroupBox.Style.Color := clWhite;
    // Up
    if FCollapseDirection = cdUp then
    begin
      FGroupBox.Alignment := alTopLeft;
      FGroupBox.Caption := FOrigGroupBoxCaption;
      FButtonPanel.Top := 0;
      FButtonPanel.Left := Width - FButtonPanel.Width - FButtonPadding;
    end
    // Right
    else if FCollapseDirection = cdRight then
    begin
      FGroupBox.Alignment := alTopLeft;
      FGroupBox.Caption := '       ' + FOrigGroupBoxCaption;
      FButtonPanel.Top := 0;
      FButtonPanel.Left := FButtonPadding;
    end
    // Left
    else if FCollapseDirection = cdLeft then
    begin
      FGroupBox.Alignment := alTopLeft;
      FGroupBox.Caption := FOrigGroupBoxCaption;
      FButtonPanel.Top := 0;
      FButtonPanel.Left := Width - FButtonPanel.Width - FButtonPadding;
    end;
  end
  // Changing to Collapsed
  else
  begin
    FGroupBox.Style.Color := clGradientActiveCaption;
    // Up
    if FCollapseDirection = cdUp then
    begin
      FGroupBox.Alignment := alTopLeft;
      FGroupBox.Caption := FOrigGroupBoxCaption;
      FButtonPanel.Top := 0;
      FButtonPanel.Left := Width - FButtonPanel.Width - FButtonPadding;
    end
    // Right
    else if FCollapseDirection = cdRight then
    begin
      FGroupBox.Alignment := alRightTop;
      FGroupBox.Caption := '       ' + FOrigGroupBoxCaption;
      FButtonPanel.Top := FButtonPadding;
      FButtonPanel.Left := FCollapsePadding;
    end
    // Left
    else if FCollapseDirection = cdLeft then
    begin
      FGroupBox.Alignment := alLeftTop;
      FGroupBox.Caption := FOrigGroupBoxCaption + '       ';
      FButtonPanel.Top := FButtonPadding;
      FButtonPanel.Left := 0;
    end;
  end;

  UpdateImage;
  // Now draw the button and invalidate Self
  Self.Invalidate;
end;

{
  TDynPanel.UpdateImage
  ---------------------------------------------------------------------------
}
procedure TDynPanel.UpdateImage();
begin
  case FCollapseDirection of
    cdUp:
      begin
        if FExpand = true then
          FButtonImage.Picture.Bitmap.LoadFromResourceName(HInstance, 'ButtonImageUp')
        else
          FButtonImage.Picture.Bitmap.LoadFromResourceName(HInstance, 'ButtonImageDown');
      end;
    cdLeft:
      begin
        if FExpand = true then
          FButtonImage.Picture.Bitmap.LoadFromResourceName(HInstance, 'ButtonImageLeft')
        else
          FButtonImage.Picture.Bitmap.LoadFromResourceName(HInstance, 'ButtonImageRight');
      end;
    cdRight:
      begin
        if FExpand = true then
          FButtonImage.Picture.Bitmap.LoadFromResourceName(HInstance, 'ButtonImageRight')
        else
          FButtonImage.Picture.Bitmap.LoadFromResourceName(HInstance, 'ButtonImageLeft');
      end;
  end;

end;

end.

靠近左边

接近顶部


Try,一个我自己编写的容器组件,可以折叠并沿其父组件的左侧或右侧对齐

接口:

property Align: TSideBarAlign default alLeft;
property AutoHide: Boolean default False;
property Hint: String;
property MinWidth: Integer default DefWidth;
property OnAutoHideChanged: TNotifyEvent;
property OnHide: TNotifyEvent;
property PinButtonDownHint: String;
property PinButtonUpHint: String;
property PinButtonVisible: Boolean default True;
property Resizable: Boolean default True;
property SideButtonWidth: Integer default DefSideButtonWidth;
property Caption;
property Color default clBtnFace;
property Font;
property ParentColor default False;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property TabOrder;
property TabStop;

或者哪一个是动画。自由使用,自由修改


抱歉自我推销,但我认为这是问题的答案。

新的Delphi版本将包括此类滑动面板(通过FireMonkey的集成,形式上是vgScene/dxScene)。您只需单击高度或位置道具,一个选项将允许为此创建动画,具有各种选项(插值类型、持续时间等)


自2009版以来,您可以在其中添加TCategoryPanel。

折叠面板
请参见此处的FoldingPanel v1.3: 我用了好几年了。
它还带有漂亮的V形位图。
小问题:它不支持复合控件(如TLabeledEdit)。
优点:该组件作为单个PAS文件提供(易于安装到调色板中)。他们说它适用于Delphi 5,但我已将其安装在XE7中,并且可以正常工作(这表示质量)。
免费软件

TSplitView
如果你有更新版本的Delphi(比如东京),你可以使用TSplitView。 注意:缺少“对齐”属性。一开始,它似乎只能向左对齐。但事实并非如此。它不是Align属性,而是Placement属性(具有两个值:svpRight/svpLeft)。
注意:它有一些与控件大小/位置相关的小故障。
注意:它没有折叠面板那么完整(甚至到目前为止)。您仍然需要编写一些代码来实现某种V形以折叠/扩展面板。

免费软件(如果你有德尔福东京)

TCategoryPanelGroup
另请看TCategoryPanelGroup。它可能工作,也可能不工作,这取决于您需要它做什么。

免费软件(如果你有Delphi XE7)

你不必为自我推广道歉,只要你公开你的参与,这是完全可以接受的。我将永远支持免费开源内容的自我推广!如果他们完美地回答了这个问题,我将永远支持自我提升。而且你似乎永远也不会更新它,超越Delphi 7:-)我在xe2中尝试了它,放置了两个右侧面板-遗憾的是,我的行为不够直观。。。我猜你总是只有一个面板在旁边:-)@Arioch'谢谢!这是一只虫子。在
updateplace
中的每个块末尾添加
BringToFront
。本文可能有用:请参见此处的FoldingPanel v1.3:我使用了多年。也有一个漂亮的V形位图。谢谢!“我需要的不是一个可调整大小的面板,而是一个可以水平滑动的面板”这一个是不可调整大小的。。。但是,它只是垂直的;o(如果OP使用Firemonkey,这将是一个很好的答案。你不能很容易地在VCL应用程序中使用FMX控件:-)我同意JD。在这里提到Firemonkey没有帮助,看起来不错。但是,您没有指定许可证:-)这是否说明可以选择将两个或三个侧边栏并排放置?@Arioch'the我认为代码包含在默认的StackOverflow CC许可证中。如果你需要与我不同的东西,你可以在“未经许可”的情况下使用。我没有尝试过多个项目并排。我们将其与流面板垂直使用。我们的主编辑屏幕上有10多个这样的页面,它们堆叠在一个流面板上,然后在一个滚动框中。CC也有许多“版本”。“我认为该代码包含在默认的StackOverflow CC许可证中”-您可能会这样认为,但是任何试图使用它的人都将面临“安全性比抱歉性好”的问题。我可以接受任何非病毒牙线许可证,但由于时间不够,我可能会坚持使用TCategoryPnel,尽管它不能满足我的所有愿望……您与我们分享了一个不错的选择。