Delphi-对接表单隐藏面板

Delphi-docking form hides panel

我有一个问题,停靠窗体隐藏了面板内的一些其他组件。

这是我的问题的简单示例:我将 Panel1 的 DockSite 设置为 True。 Panel1 内部是 Panel2。面板 2 对齐到客户端 (Align=alClient)。 Panel2 内部是也与客户端对齐的备注字段。它与整个 Panel1 重叠。 我有另一个窗体 (Form2),我想停靠到 Panel1。但它与整个 Panel1 重叠并隐藏了备忘。我只想重叠 Panel1 的一部分(表格的宽度)并将 Panel2 移到右边或左边。

主要形式:

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
  TForm1 = class(TForm)
    Button1: TButton;
    Panel1: TPanel;
    Panel2: TPanel;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses Unit2;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2.Show;
end;

end.


object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 333
  ClientWidth = 754
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -12
  Font.Name = 'Segoe UI'
  Font.Style = []
  PixelsPerInch = 96
  TextHeight = 15
  object Button1: TButton
    Left = 288
    Top = 271
    Width = 153
    Height = 41
    Caption = 'Show dockable form'
    TabOrder = 0
    OnClick = Button1Click
  end
  object Panel1: TPanel
    Left = 8
    Top = 8
    Width = 729
    Height = 257
    Caption = 'Panel1'
    DockSite = True
    TabOrder = 1
    object Panel2: TPanel
      Left = 1
      Top = 1
      Width = 727
      Height = 255
      Align = alClient
      Caption = 'Panel2'
      TabOrder = 0
      ExplicitLeft = 360
      ExplicitTop = 8
      ExplicitWidth = 337
      ExplicitHeight = 241
      object Memo1: TMemo
        Left = 1
        Top = 1
        Width = 725
        Height = 253
        Align = alClient
        Lines.Strings = (
          'Memo1')
        TabOrder = 0
        ExplicitWidth = 216
        ExplicitHeight = 144
      end
    end
  end
end

对接形式:

unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm2 = class(TForm)
    Label1: TLabel;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

end.

object Form2: TForm2
  Left = 0
  Top = 0
  Caption = 'Form2'
  ClientHeight = 103
  ClientWidth = 273
  Color = clBtnFace
  DragKind = dkDock
  DragMode = dmAutomatic
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -12
  Font.Name = 'Segoe UI'
  Font.Style = []
  PixelsPerInch = 96
  TextHeight = 15
  object Label1: TLabel
    Left = 22
    Top = 24
    Width = 227
    Height = 45
    Caption = 'Dockable form'
    DragKind = dkDock
    DragMode = dmAutomatic
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -33
    Font.Name = 'Segoe UI'
    Font.Style = []
    ParentFont = False
  end
end

随着停靠站点的变化和对齐方式的变化,动态很快变得难以掌握,但我认为以下内容会满足您的要求。

Form1 的层次结构更改为以下,并注意 Panel2Memo1 都是 Panel1 的子级。 Panel2 将作为对接目标。我已将 Panel2.Width 设置为 8,以便在可视区域放置 Form2。以下是基本属性:

object Form1: TForm1
  object Button1: TButton
  object Panel1: TPanel
    Caption = 'Panel1'
    object Panel2: TPanel
      Width = 8
      Align = alRight
      Caption = 'Panel2'
      DockSite = True
      OnDockDrop = Panel2DockDrop
      OnDockOver = Panel2DockOver
      OnUnDock = Panel2UnDock
    end
    object Memo1: TMemo
      Align = alClient
    end
  end
end

Form2 被拖到 Panel2 上时,会触发 OnDockOver 事件。 Panel2 将其宽度设置为 Panel1 宽度的一半,这又将 Memo1 宽度减小了相同的量。 (根据需要更改)

procedure TForm1.Panel2DockOver(Sender: TObject; Source: TDragDockObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
  Panel2.Width := Panel1.Width div 2;
end;

Form2落在Panel2上时,表格的DockRect设置为Panel2的矩形。

procedure TForm1.Panel2DockDrop(Sender: TObject; Source: TDragDockObject; X, Y: Integer);
begin
  Source.DockRect := Rect(Panel2.Width, Panel2.Top, Panel2.Width, Panel2.Height);
end;

Form2Panel2 分离时,它会将其宽度减小到 8 个像素,这再次将 Memo1 加宽到其原始宽度。

procedure TForm1.Panel2UnDock(Sender: TObject; Client: TControl; NewTarget: TWinControl;
  var Allow: Boolean);
begin
  Panel2.Width := 8;
end;

这是 Form1 的完整 .dfm

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 333
  ClientWidth = 425
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -12
  Font.Name = 'Segoe UI'
  Font.Style = []
  OldCreateOrder = True
  PixelsPerInch = 96
  TextHeight = 15
  object Button1: TButton
    Left = 120
    Top = 284
    Width = 153
    Height = 41
    Caption = 'Show dockable form'
    TabOrder = 0
    OnClick = Button1Click
  end
  object Panel1: TPanel
    Left = 8
    Top = 8
    Width = 400
    Height = 257
    Caption = 'Panel1'
    TabOrder = 1
    object Panel2: TPanel
      Left = 391
      Top = 1
      Width = 8
      Height = 255
      Align = alRight
      Caption = 'Panel2'
      DockSite = True
      TabOrder = 0
      OnDockDrop = Panel2DockDrop
      OnDockOver = Panel2DockOver
      OnUnDock = Panel2UnDock
      ExplicitLeft = 394
    end
    object Memo1: TMemo
      Left = 1
      Top = 1
      Width = 390
      Height = 255
      Align = alClient
      Lines.Strings = (
        'Memo1')
      TabOrder = 1
      ExplicitWidth = 725
      ExplicitHeight = 253
    end
  end
end