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 如何在TCustomControl组件上正确创建TSplitter?_Delphi_Components - Fatal编程技术网

Delphi 如何在TCustomControl组件上正确创建TSplitter?

Delphi 如何在TCustomControl组件上正确创建TSplitter?,delphi,components,Delphi,Components,我正在使用一组现有的TControl设计一个新的VCL组件。 控制装置放置在Tpanel上,一些对准左侧位置,一个对准右侧位置,最后一个对准客户区域。这些面板中的每一个都有自定义组件作为其父组件 我需要在面板之间放置拆分器,以便用户能够调整内部组件的大小 问题是,我无法理解在运行时创建拆分器时应用于拆分器定位的逻辑 我访问了很多论坛,每个论坛都指向不同的解决方案,但没有一个有效 试图: 1-创建拆分器时,使用组件的“左”属性和其应放置在一旁的宽度作为其“左”属性 2-使用left属性指定其应位于

我正在使用一组现有的TControl设计一个新的VCL组件。 控制装置放置在Tpanel上,一些对准左侧位置,一个对准右侧位置,最后一个对准客户区域。这些面板中的每一个都有自定义组件作为其父组件

我需要在面板之间放置拆分器,以便用户能够调整内部组件的大小

问题是,我无法理解在运行时创建拆分器时应用于拆分器定位的逻辑

我访问了很多论坛,每个论坛都指向不同的解决方案,但没有一个有效

试图:

1-创建拆分器时,使用组件的“左”属性和其应放置在一旁的宽度作为其“左”属性

2-使用left属性指定其应位于的位置

还有一些我不记得了

我错过了什么

在下面的代码中,将在应该创建拆分器的位置创建拆分器。 就在相应的面板之后,他们的左属性对应于我最后一次尝试它的位置

constructor TDBIDBGridFilterBar.Create(AOwner: TComponent);
begin
  inherited;
  Self.Width := 490;
  Self.Height := 23;
  Self.Constraints.MinWidth := 285;

  if fComboColunasWidth = 0 then
    fComboColunasWidth := 118;

  fBackGroundPanel := TPanel.Create(Self);
  fBackGroundPanel.Parent := Self;
  fBackGroundPanel.ShowCaption := false;
  fBackGroundPanel.BevelOuter := bvNone;
  fBackGroundPanel.Align := alClient;

  fButtonsPanel := TPanel.Create(Self);
  fButtonsPanel.Parent := fBackGroundPanel;
  fButtonsPanel.ShowCaption := false;
  fButtonsPanel.BevelOuter := bvNone;
  fButtonsPanel.Width := 73;
  fButtonsPanel.Align := alLeft;

  fBtnMarcaTodos := TButton.Create(Self);
  fBtnMarcaTodos.Parent := fButtonsPanel;
  fBtnMarcaTodos.Width := 23;
  fBtnMarcaTodos.Height := 23;
  fBtnMarcaTodos.Left := 0;
  fBtnMarcaTodos.Hint := 'Marcar todos';
  fBtnMarcaTodos.ShowHint := true;

  fBtnDesmarcaTodos := TButton.Create(Self);
  fBtnDesmarcaTodos.Parent := fButtonsPanel;
  fBtnDesmarcaTodos.Width := 23;
  fBtnDesmarcaTodos.Height := 23;
  fBtnDesmarcaTodos.Left := 23;
  fBtnDesmarcaTodos.Hint := 'Desarcar todos';
  fBtnDesmarcaTodos.ShowHint := true;

  fBtnInveteSelecao := TButton.Create(Self);
  fBtnInveteSelecao.Parent := fButtonsPanel;
  fBtnInveteSelecao.Width := 23;
  fBtnInveteSelecao.Height := 23;
  fBtnInveteSelecao.Left := 46;
  fBtnInveteSelecao.Hint := 'Inverter seleção';
  fBtnInveteSelecao.ShowHint := true;

  fLabelPanel := TPanel.Create(Self);
  fLabelPanel.Parent := fBackGroundPanel;
  fLabelPanel.Width := 33;
  fLabelPanel.Align := alLeft;
  fLabelPanel.ShowCaption := false;
  fLabelPanel.BevelOuter := bvNone;

  fLabel := TLabel.Create(Self);
  fLabel.Parent := fLabelPanel;
  fLabel.Top := 4;
  fLabel.Left := 4;
  fLabel.Caption := 'Filtro:';
  fLabel.Width := 28;

  fComboColunasPan := TPanel.Create(Self);
  fComboColunasPan.Parent := fBackGroundPanel;
  fComboColunasPan.ShowCaption := false;
  fComboColunasPan.BevelOuter := bvNone;
  fComboColunasPan.width := fComboColunasWidth;
  fComboColunasPan.Align := alLeft;

  fComboColunas := TDBIComboBox.Create(Self);
  fComboColunas.Parent := fComboColunasPan;
  fComboColunas.Text := '';
  fComboColunas.OnEnter := PopulaComboColunas;
  fComboColunas.OnChange := ComboChange;
  fComboColunas.Style := csOwnerDrawFixed;
  fComboColunas.Align := alClient;
  fComboColunas.Hint := 'Colunas';
  fComboColunas.ShowHint := true;

  fSplitterColunas := TSplitter.Create(Self);
  fSplitterColunas.Parent := fBackGroundPanel;
  fSplitterColunas.Align := alLeft;
  fSplitterColunas.Left := 1;

  fComboOperadorPan := TPanel.Create(Self);
  fComboOperadorPan.Parent := fBackGroundPanel;
  fComboOperadorPan.ShowCaption := false;
  fComboOperadorPan.BevelOuter := bvNone;
  fComboOperadorPan.width := fComboColunasWidth;
  fComboOperadorPan.Align := alLeft;

  fComboOperador := TDBIComboBox.Create(Self);
  fComboOperador.Parent := fComboOperadorPan;
 // fComboOperador.Items.Add(cItensComboFiltro);
  fComboOperador.Style := csOwnerDrawFixed;
  fComboOperador.Align := alClient;
  fComboOperador.Hint := 'Comparação';
  fComboOperador.ShowHint := true;
  fComboOperador.Text := '  =  ';

  fSplitterOperador := TSplitter.Create(Self);
  fSplitterOperador.Parent := fBackGroundPanel;
  fSplitterOperador.Align := alLeft;
  fSplitterOperador.Left := 2;

  fBtnAdcFiltroPan := TPanel.Create(Self);
  fBtnAdcFiltroPan.Parent := fBackGroundPanel;
  fBtnAdcFiltroPan.ShowCaption := false;
  fBtnAdcFiltroPan.BevelOuter := bvNone;
  fBtnAdcFiltroPan.width := 23;
  fBtnAdcFiltroPan.Align := alRight;

  fBtnAdcFiltro := TButton.Create(Self);
  fBtnAdcFiltro.Parent := fBtnAdcFiltroPan;
  fBtnAdcFiltro.Height := 23;
  fBtnAdcFiltro.Width := 23;
  fBtnAdcFiltro.Caption := '+';
  fBtnAdcFiltro.Hint := 'Adicionar filtro...';
  fBtnAdcFiltro.ShowHint := true;
  fBtnAdcFiltro.OnClick := btnNewFilterClick;

  fClientPanel := TPanel.Create(Self);
  fClientPanel.Parent := fBackGroundPanel;
  fClientPanel.ShowCaption := false;
  fClientPanel.BevelOuter := bvNone;
  fClientPanel.Align := AlClient;

  fMaskEdit := TDBIMaskEdit.Create(Self);
  fMaskEdit.Parent := fClientPanel;
  fMaskEdit.Font.Size := 9;
  fMaskEdit.Align := alTop;
end;

我设法弄明白了。 因为之前创建的所有组件都是左对齐的,所以它们的“左”属性设置为0,而不管它们位于表单中的何处

因此,为了解决这个问题,我必须适当地填充前面面板的left属性


fThisPanel.left:=fPreviousPanel.left+fPreviousPanel.width+1,依此类推……

将面板按从左到右的顺序添加到背景面板时,在将对齐属性设置为足够大的值之前,设置所添加面板的left属性就足够了,因此,它超出了已放置在背景面板上的组件的Left属性。设置的值甚至可以大于背景面板的宽度

以从右到左的顺序添加面板或其他组件时,对齐=正常;您可以将Left属性保留为0

对于放置在背景面板上的任何组件,也包括拆分器,上述情况都是正确的。使用拆分器时,您可能还希望将相邻组件Constraints.MinWidth属性设置为类似于10的值,以防止组件宽度意外减小为零,从而变得不可见。一旦发生这种情况,就无法使用拆分器使其再次可见

例如,此代码:

procedure TForm1.Panel1Click(Sender: TObject);
var
  i: integer;
begin
  i := 1;
  repeat
    with TPanel.Create(self) do
    begin
      Parent := Panel1;
      Left := 510;
      Align := alLeft;
      Width := 40;
      Constraints.MinWidth := 10;
      Caption := 'L'+IntToStr(i);
    end;
    if (i = 3) or (i = 5) then
    with TSplitter.Create(self) do
    begin
      Parent := Panel1;
      Left := 510;
      Width := 10;
      Align := alLeft;
    end;
    inc(i);
  until i > 5;
  with TPanel.Create(self) do
  begin
    Parent := Panel1;
    Width := 40;
    Align := alRight;
    Caption := 'R1';
  end;
  with TPanel.Create(self) do
  begin
    Parent := Panel1;
    Width := 40;
    Align := alRight;
    Caption := 'R2';
  end;
  with TPanel.Create(self) do
  begin
    Parent := Panel1;
    Left := 510;
    Align := alClient;
    Caption := 'C';
  end;
end;
生成此设计:


L1。。L5对齐,C对齐,R1对齐。。R2可以对齐。

应该是LeftSplitter。Left:=控件左侧宽度+1;大概没有测试你的代码。简单地将其设置为精确的宽度不会起作用。然而,这样的设计会给你带来伤害。自定义控件不应以这种方式具有子控件。在您的情况下,编写嵌入式TFrame甚至TForm更合适。所有这些都放在自定义控件中是毫无意义的。谢谢你的快速回复。我会尝试一下,但逻辑上不应该是LeftSplitter。Left:=ControlOnLeft.Left+ControlOnLeft.Width+1这样,我应该得到正确的位置+1。它不起作用,该死的拆分器一直在客户端对齐面板的左侧。没有必要为要在彼此之后左对齐的面板计算left属性。因为是按从左到右的顺序创建它们,所以在设置对齐之前,只需将left属性设置为足够大的数字,如480(如果父对象是fBackGroundPanel)。