Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.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 如何使用Align属性调整TFlowPanel内控件的大小?_Delphi_Flowpanel - Fatal编程技术网

Delphi 如何使用Align属性调整TFlowPanel内控件的大小?

Delphi 如何使用Align属性调整TFlowPanel内控件的大小?,delphi,flowpanel,Delphi,Flowpanel,我在TFlowPanel中有几个控件(即TDBChart)。当用户单击其中一个时,我希望它填充整个流面板的客户区。但是,在运行时更改流面板中子控件的可见和对齐属性似乎没有任何效果。这有什么特别的窍门吗?我找到了reallign()方法,但它似乎对控件的布局没有任何影响。以下是我的OnClick事件的代码: var AChart: TDBChart; V: Boolean; i: Integer; begin AChart := TDBChart(Sender); if ACh

我在
TFlowPanel
中有几个控件(即
TDBChart
)。当用户单击其中一个时,我希望它填充整个
流面板的客户区。但是,在运行时更改
流面板
中子控件的
可见
对齐
属性似乎没有任何效果。这有什么特别的窍门吗?我找到了
reallign()
方法,但它似乎对控件的布局没有任何影响。以下是我的
OnClick
事件的代码:

var
  AChart: TDBChart;
  V: Boolean;
  i: Integer;
begin
  AChart := TDBChart(Sender);
  if AChart.Align = alNone then
  begin
    V := False;
    AChart.Align := alClient;
  end else begin
    V := True;
    AChart.Align := alNone;
  end;
  for i := 0 to FlowPanel1.ControlCount - 1 do
    if FlowPanel1.Controls[i] is TDBChart then
      if FlowPanel1.Controls[i] <> AChart then
        FlowPanel1.Controls[i].Visible := V;
end;
var
AChart:TDBChart;
V:布尔型;
i:整数;
开始
AChart:=TDBChart(发送方);
如果AChart.Align=alNone,则
开始
V:=假;
AChart.Align:=alClient;
结束,否则开始
V:=真;
AChart.Align:=alNone;
结束;
对于i:=0到FlowPanel1.ControlCount-1 do
如果FlowPanel1.Controls[i]为TDBChart,则
如果FlowPanel1.控制[i]AChart,则
FlowPanel1.控件[i]。可见:=V;
结束;

图表按预期隐藏或显示,但
ADBChart
不会填充整个
流程面板的客户区。

流程面板不关心控件的对齐设置,就像不关心控件的位置一样-它的设计只是为了让它们流动

一种解决方案是派生一个新类并重写
AlignControls
,并在其中相应地调整将填充曲面的控件的大小。例如:

type
  TFlowPanel = class(extctrls.TFlowPanel)
  protected
    procedure AlignControls(AControl: TControl; var Rect: TRect); override;
  end;

..

procedure TFlowPanel.AlignControls(AControl: TControl; var Rect: TRect);
var
  i, VisibleCount, VisibleControl: Integer;
begin
  VisibleCount := 0;
  VisibleControl := 0;
  for i := 0 to ControlCount - 1 do
    if Controls[i].Visible then begin
      Inc(VisibleCount);
      VisibleControl := i;
    end;

  if (VisibleCount = 1) and (Controls[VisibleControl] = AControl) and
      (AControl.Align = alClient) then begin
    // preserve 'Explicit..' settings
    AControl.ControlState := AControl.ControlState + [csAligning];
    AControl.SetBounds(1, 1, ClientWidth - 1, ClientHeight -1);
    AControl.ControlState := AControl.ControlState - [csAligning];
  end;

  inherited;
end;
然后,您可以将所有图表的单击事件设置为此处理程序:

var
  AChart: TTDBChart;

  procedure SetVisibility(Visible: Boolean);
  var
    i: Integer;
  begin
    for i := 0 to FlowPanel1.ControlCount - 1 do
      if FlowPanel1.Controls[i] is TDBChart then
        if FlowPanel1.Controls[i] <> AChart then
          FlowPanel1.Controls[i].Visible := Visible;
  end;

begin
  AChart := TDBChart(Sender);
  if AChart.Align = alNone then
  begin
    SetVisibility(False);
    AChart.Align := alClient;
  end else begin
    AChart.Align := alNone; // set before changing visible
    SetVisibility(True);
    AChart.SetBounds(0, 0, AChart.ExplicitWidth, AChart.ExplicitHeight);
  end;
end;
var
AChart:TTDBChart;
过程集合可见性(可见:布尔值);
变量
i:整数;
开始
对于i:=0到FlowPanel1.ControlCount-1 do
如果FlowPanel1.Controls[i]为TDBChart,则
如果FlowPanel1.控制[i]AChart,则
FlowPanel1.控件[i]。可见:=可见;
结束;
开始
AChart:=TDBChart(发送方);
如果AChart.Align=alNone,则
开始
设置可见性(假);
AChart.Align:=alClient;
结束,否则开始
AChart.Align:=alNone;//更改前设置为可见
设置可见性(真);
AChart.SetBounds(0,0,AChart.ExplicitWidth,AChart.ExplicitHeight);
结束;
结束;
我应该注意,这只适用于固定大小的flowpanel。

根据设计,
T(自定义)flowpanel
使用子控件的自定义对齐,这是通过重写的
AlignControls
方法实现的

您可以通过跳过该默认行为,从它的祖先那里返回该默认行为来防止它。此外,不需要隐藏所有相邻控件。把点击的图表放在前面就足够了

type
  TFlowPanel = class(Vcl.ExtCtrls.TFlowPanel)
  private
    FFlowDisabled: Boolean;
    procedure SetFlowDisabled(Value: Boolean);
  protected
    procedure AlignControls(AControl: TControl; var Rect: TRect); override;
  public
    property FlowDisabled: Boolean read FFlowDisabled write SetFlowDisabled;
  end;

...

{ TFlowPanel }

type
  TWinControlAccess = class(TWinControl);
  TAlignControls = procedure(Instance: TObject; AControl: TControl;
    var Rect: TRect);

procedure TFlowPanel.AlignControls(AControl: TControl; var Rect: TRect);
begin
  if FFlowDisabled then
    // Skip inherited in TCustomFlowPanel:
    TAlignControls(@TWinControlAccess.AlignControls)(Self, AControl, Rect)
  else
    inherited;
end;

procedure TFlowPanel.SetFlowDisabled(Value: Boolean);
begin
  if FFlowDisabled <> Value then
  begin
    FFlowDisabled := Value;
    Realign;
  end;
end;    

{ TForm1 }

procedure TForm1.DBChartClick(Sender: TObject);
const
  FlowAligns: array[Boolean] of TAlign = (alNone, alClient);
var
  Chart: TDBChart;
  Panel: TFlowPanel;
  DisableFlow: Boolean;
begin
  Chart := TDBChart(Sender);
  Panel := Chart.Parent as TFlowPanel;
  DisableFlow := not Panel.FlowDisabled;
  Chart.Align := FlowAligns[DisableFlow];
  Chart.BringToFront;
  Panel.FlowDisabled := DisableFlow;
end;
类型
TFlowPanel=class(Vcl.ExtCtrls.TFlowPanel)
私有的
FFlowDisabled:布尔值;
过程SetFlowDisabled(值:布尔);
受保护的
过程控制(a控制:t控制;var Rect:t控制);推翻
公众的
属性FlowDisabled:布尔读取FFlowDisabled写入SetFlowDisabled;
结束;
...
{TFlowPanel}
类型
TWinControlAccess=类(TWinControl);
TAlignControls=过程(实例:ToObject;AControl:TControl;
var-Rect:TRect);
程序TFlowPanel.AlignControls(A控制:TControl;变量Rect:TRect);
开始
如果禁用,则
//TCustomFlowPanel中继承的跳过:
TAlignControls(@TWinControlAccess.AlignControls)(Self、AControl、Rect)
其他的
继承;
结束;
过程TFlowPanel.SetFlowDisabled(值:布尔);
开始
如果FFlowDisabled值,则
开始
FFlowDisabled:=值;
重新排列
结束;
结束;
{TForm1}
过程TForm1.DBChartClick(发送方:TObject);
常数
FlowAligns:TAlign=(alNone,alClient)的数组[Boolean];
变量
图表:TDBChart;
面板:TFlowPanel;
禁用流:布尔;
开始
图表:=TDBChart(发送方);
面板:=图表。父级为TFlowPanel;
DisableFlow:=非面板。FlowDisabled;
Chart.Align:=流程对齐[禁用流程];
海图.布林托夫隆;
Panel.FlowDisabled:=禁用流;
结束;

工作起来很有魅力,但我必须硬编码
AChart.explicittwith
AChart.ExplicitHeight
。Thanks@iMan->“。必须硬编码..”>然后可以从“AlignControls”中删除“ControlState:=”语句。或者,相反,您可以尝试在设置对齐和可见性的同时在单击处理程序中设置标志。无论如何,不客气!很好的“放大流程面板”-问题!我想这也会考虑到一个可调整大小的flowpanel。@Sertac是的,我在所有锚都打开的情况下对它进行了测试。