문제

삭제 및 추가 패널 버튼을 포함하여 각각 몇 가지 구성 요소가있는 동적으로 만든 패널로 구성된 프로그램을 작성하고 있습니다. 각 패널은 20 픽셀을 표시합니다. 패널 번호가 서로 아래로 표시되고, Add의 OnClick은 세트의 끝에 다른 패널을 추가해야하며 삭제를 위해 OnClick은 부모를 파괴 한 다음 다른 모든 패널을 삭제하는 공간으로 이동해야합니다. 내가 이미 시도한 방법은 배열을 사용하여 관련되었지만 불행히도 나는 그 중간에 객체를 삭제 한 배열을 통해 반복 할 때 eaccessviolation을 얻었습니다.

이것이 명백하거나 이전에 답변 된 경우 죄송합니다. 그러나 나는 이번 주 초에 나 자신을 가르치기 시작했기 때문에 모든 용어를 알지 못하거나 클래스가 나에게 이런 일을 할 배열이 있는지 모르겠습니다.

도움이 되었습니까?

해결책

정렬 속성을 신중하게 사용 하여이 작업을 수행하는 것이 좋습니다.

여기에 표시된대로 정렬 된 3 개의 패널이있는 경우 :

|-----------------------|
|                       |
|        alTop          |
|                       |
|-----------------------|

|-----------------------|
|                       |
|        alTop          |
|                       |
|-----------------------|

|-----------------------|
|                       |
|        alTop          |
|                       |
|-----------------------|

그리고 두 번째를 삭제하면 세 번째는 자동으로 그 장소로 튀어 나옵니다.

3 개의 패널을 다른 부모 컨트롤 (즉, 다른 패널) 안에 배치하여 "altop"이라고 말할 때 "상단"이 무엇을 의미하는지 정의하십시오.

그 효과를 애니메이션하고 싶다면 약간 더 좋아해야합니다. 그게 당신의 목표인가요? 그렇다면, 우리가 무언가를 생각해 낼 수 있다고 확신합니다.

편집 - 나는 당신에게 몇 가지 아이디어를 줄 수있는 몇 가지 코드를 썼습니다.

unit Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, ExtCtrls;

type
  TWhere = (wAtBeginning, wAtEnd);

type
  TfrmMain = class(TForm)
    panCtrl: TPanel;
    panHost: TPanel;
    btnAddPan: TBitBtn;
    btnDelPan: TBitBtn;
    lbAddWhere: TListBox;
    lbDelWhere: TListBox;
    procedure btnAddPanClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure btnDelPanClick(Sender: TObject);
  private
    function GetPanel(HostPanel: TPanel; Where: TWhere): TPanel;
    function BottomOfLastPanel(HostPanel: TPanel): integer;
    procedure AddPanel(HostPanel: TPanel; AddWhere: TWhere);
    procedure DelPanel(HostPanel: TPanel; DelWhere: TWhere);
    procedure DelThisPanel(Sender: TObject);
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}

procedure TfrmMain.AddPanel(HostPanel: TPanel; AddWhere: TWhere);
var
  pnl: TPanel;
  btn: TBitBtn;
begin
  pnl := TPanel.Create(HostPanel);
  with pnl do begin
    case AddWhere of
      wAtBeginning: Top := 0;
      wAtEnd: Top := BottomOfLastPanel(HostPanel);
    end;
    Align := alTop;
    Parent := HostPanel;
    Caption := DateTimeToStr(Now);
  end;

  btn := TBitBtn.Create(pnl);
  with btn do begin
    Parent := pnl;
    Left := 0;
    Top := 0;
    Width := 100;
    Height := 30;
    Align := alLeft;
    Caption := 'Delete this panel';
    OnClick := DelThisPanel;
  end;
end;

function TfrmMain.BottomOfLastPanel(HostPanel: TPanel): integer;
begin
  //scan through all panels contained inside the host panel
  //return the bottom of the lowest one (highest "top" value)
  Result := 0;
  if Assigned(GetPanel(HostPanel,wAtEnd)) then begin
    Result := GetPanel(HostPanel,wAtEnd).Top + GetPanel(HostPanel,wAtEnd).Height;
  end;
end;

procedure TfrmMain.btnAddPanClick(Sender: TObject);
begin
  case lbAddWhere.ItemIndex of
    0: AddPanel(panHost,wAtBeginning);
    1: AddPanel(panHost,wAtEnd);
  end;
end;

procedure TfrmMain.btnDelPanClick(Sender: TObject);
begin
  case lbDelWhere.ItemIndex of
    0: DelPanel(panHost,wAtBeginning);
    1: DelPanel(panHost,wAtEnd);
  end;
end;

procedure TfrmMain.DelPanel(HostPanel: TPanel; DelWhere: TWhere);
var
  pnlToDelete: TPanel;
begin
  case DelWhere of
    wAtBeginning: pnlToDelete := GetPanel(HostPanel,wAtBeginning);
    wAtEnd: pnlToDelete := GetPanel(HostPanel,wAtEnd);
  end;
  if Assigned(pnlToDelete) then begin
    FreeAndNil(pnlToDelete);
  end;
end;

procedure TfrmMain.DelThisPanel(Sender: TObject);
var
  parentPnl: TPanel;
begin
  //delete the parent panel of this button
  if Sender is TBitBtn then begin
    if (Sender as TBitBtn).Parent is TPanel then begin
      parentPnl := (Sender as TBitBtn).Parent as TPanel;
      parentPnl.Parent := nil;
      FreeAndNil(parentPnl);
    end;
  end;
end;

procedure TfrmMain.FormShow(Sender: TObject);
begin
  lbAddWhere.ItemIndex := 1;
  lbDelWhere.ItemIndex := 1;
end;

function TfrmMain.GetPanel(HostPanel: TPanel; Where: TWhere): TPanel;
var
  i: integer;
begin
  Result := nil;
  for i := 0 to panHost.ControlCount - 1 do begin
    if panHost.Controls[i] is TPanel then begin
      Result := (panHost.Controls[i] as TPanel);
      if Where = wAtBeginning then begin
        Break;
      end;
    end;
  end;
end;

end.

그리고 다음은 DFM의 코드입니다.

object frmMain: TfrmMain
  Left = 0
  Top = 0
  Caption = 'Add / Delete Panel Demo'
  ClientHeight = 520
  ClientWidth = 637
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnShow = FormShow
  PixelsPerInch = 96
  TextHeight = 13
  object panCtrl: TPanel
    Left = 0
    Top = 0
    Width = 305
    Height = 520
    Align = alLeft
    TabOrder = 0
    object btnAddPan: TBitBtn
      Left = 8
      Top = 8
      Width = 125
      Height = 75
      Caption = 'Add panel'
      TabOrder = 0
      OnClick = btnAddPanClick
    end
    object btnDelPan: TBitBtn
      Left = 8
      Top = 89
      Width = 125
      Height = 75
      Caption = 'Remove panel'
      TabOrder = 1
      OnClick = btnDelPanClick
    end
    object lbAddWhere: TListBox
      Left = 139
      Top = 8
      Width = 150
      Height = 75
      Font.Charset = DEFAULT_CHARSET
      Font.Color = clWindowText
      Font.Height = -13
      Font.Name = 'Tahoma'
      Font.Style = []
      ItemHeight = 16
      Items.Strings = (
        'Add to the top'
        'Add to the bottom')
      ParentFont = False
      TabOrder = 2
    end
    object lbDelWhere: TListBox
      Left = 139
      Top = 89
      Width = 150
      Height = 75
      Font.Charset = DEFAULT_CHARSET
      Font.Color = clWindowText
      Font.Height = -13
      Font.Name = 'Tahoma'
      Font.Style = []
      ItemHeight = 16
      Items.Strings = (
        'Delete from the top'
        'Delete from the bottom')
      ParentFont = False
      TabOrder = 3
    end
  end
  object panHost: TPanel
    Left = 305
    Top = 0
    Width = 332
    Height = 520
    Align = alClient
    TabOrder = 1
    ExplicitLeft = 392
    ExplicitTop = 264
    ExplicitWidth = 185
    ExplicitHeight = 41
  end
end

다른 팁

동적 배열을 사용하고 패널을 제거 할 때 실제로 요소를 삭제하는 경우 배열 전략을 사용할 수 있습니다. 또는 요소가 할당 된 경우 (Array [i])와 함께 할당되는지 언제든지 확인할 수 있습니다.

그러나 배열 솔루션을 TcomponentList를 사용하여 솔루션으로 배열 솔루션을 교체하여 목록에 패널을 더 쉽게 추가하고 삭제할 수 있으며 이러한 유형의 상황에 맞게 설계되었습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top