如图1:
     -----------------
    |     P1             |
    |________________________________|
    |                 |
    |                 |
    |                 |
    |                 |
    |________________________________|
    |     P2             |
    |________________________________|
    |     P3             |
    |________________________________|
    |     P4             |
    |________________________________|
    |     P5             |
    |________________________________|
   
在一个在的panel上放有panel P1~P5,我想实现的效果是:当我点击P4时,P2、P3、P4一齐上移,而且要按顺序排列,如图2: 
     -----------------
    |     P1             |
    |________________________________|
    |     P2             |
    |________________________________|
    |     P3             |
    |________________________________|
    |     P4             |
    |________________________________|
    |                 |
    |                 |
    |                 |
    |                 |
    |________________________________|
    |     P5             |
    |________________________________|
如果在点击P1时又恢复图1的效果,点击P2、P3的效果相类似。
想了很久,也试了很多,使用过panel的Align、Controls、ControlCount、Tag等属性,但效果还是做不出来,望高手指点!
补充一点:不使用控件!!

解决方案 »

  1.   

    呵呵,你是不是想实现类似qq的面板,这样好了:做两个面板第一个如上图,第二个如下图,根据条件使其中的一个visible=true;
    我以前做考勤的时候就是这样实现qq风格的主界面
      

  2.   

    http://www.51delphi.com/上有个DevExpress ExpressBar 5.1 控件TdxSideBar见贴http://expert.csdn.net/Expert/topic/2292/2292481.xml?temp=.3202936
      

  3.   

    假设这5个Panel放在Pan0 上,P1..P5的tag分别为1..5;
    在p1..p5面版的事件里写如下代码var i, g:integer;
    begin
      g:=TControl(Sender).Tag;  for i:=0 to Pan0.ControlsCount-1 do 
         if TPan0.Controls[i] is TPanel then TPanel(TPan0.Controls[i]).Align:=alDown;  for i:=0 to Pan0.ControlsCount-1 do 
         if (TPan0.Controls[i] is TPanel) and (TPan0.Controls[i].Tag<=g) then 
      begin
         TPanel(TPan0.Controls[i]).Align:=alTop;
      end;end;end;这段代码我没测试,可能编译的时候有些问题,但这种思路我以前用过。
      

  4.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ExtCtrls;type
      TForm1 = class(TForm)
        Panel1: TPanel;
        Panel2: TPanel;
        Panel3: TPanel;
        Panel4: TPanel;
        Panel5: TPanel;
        Panel6: TPanel;
        Panel7: TPanel;
        procedure treelist();
        procedure FormShow(Sender: TObject);
        procedure Panel2Click(Sender: TObject);
        procedure Panel3Click(Sender: TObject);
        procedure Panel4Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.treelist();
    begin
      Panel2.top:=10;
      Panel3.top:=60;
      Panel4.top:=110;
    end;procedure TForm1.FormShow(Sender: TObject);
    begin
    //panel5.Height :=0;panel5.Width:=141;
    //panel6.Height :=0;panel6.Width:=141;
    //panel7.Height :=0;panel7.Width:=141;
    end;procedure TForm1.Panel2Click(Sender: TObject);
    begin
    //treelist();
    //  Panel5.Left:=15;Panel5.Top:=35;
      Panel2.top:=10;
      Panel3.top:=310;
      Panel4.top:=350;
    //  Panel6.Height:=0;Panel6.Width:=141;
    //  Panel7.Height:=0;Panel7.Width:=141;
    end;procedure TForm1.Panel3Click(Sender: TObject);
    begin
    //treelist();
    //  Panel6.Left:=15;Panel6.Top:=85;
      Panel2.top:=10;
      Panel3.top:=60;
      Panel4.top:=365;
    //  Panel5.Height:=0;Panel5.Width:=141;
    //  Panel7.Height:=0;Panel7.Width:=141;
    end;procedure TForm1.Panel4Click(Sender: TObject);
    begin
    //  treelist();
    //  Panel7.Left:=15;Panel7.Top:=135;
      Panel2.top:=10;
      Panel3.top:=60;
      Panel4.top:=110;
    //  Panel5.Height:=0;Panel5.Width:=141;
    //  Panel6.Height:=0;Panel6.Width:=141;
    end;end.
      

  5.   

    提个想法:可以像做绘图程序那样,用时间控制移动的速度,反正移动也就是top值的变化而已。
    你sleep一段时间,就改变一下top的值,或者做个随时间渐变速度也渐变的算法,实现由快到慢的移动。不知可行否?
      

  6.   

    我也知道用控件可以,而且实现了,但阿头说最好不要使用控件。
    to  znxia(znxia) :
    我之前就是这样做的,但顺序会乱。顺便问一句,控件的Controls的序号可否改变?
      

  7.   

    procedure tform1.ref;
    begin
      panel5.Align:=alnone;
      panel4.Align:=alnone;
      panel3.Align:=alnone;
      panel2.Align:=alnone;
      panel1.Align:=alnone;
    end;
    procedure TForm1.Panel1Click(Sender: TObject);
    begin
      ref;
      panel5.Align:=albottom;
      panel4.Align:=albottom;
      panel3.Align:=albottom;
      panel2.Align:=albottom;
      self.Panel1.Align:=altop;
    end;procedure TForm1.Panel2Click(Sender: TObject);
    begin
      ref;  panel5.Align:=albottom;
      panel4.Align:=albottom;
      panel3.Align:=albottom;
      panel1.Align:=altop;
      self.Panel2.Align:=altop;
    end;procedure TForm1.Panel3Click(Sender: TObject);
    begin
      ref;
      panel5.Align:=albottom;
      panel4.Align:=albottom;  panel1.Align:=altop;
      self.Panel2.Align:=altop;
      panel3.Align:=altop;
    end;end.
      

  8.   

    我是这样想的,不知道可不可以实现:
    1、在设计时指定5个面板的tag值按从高到低为15
    2、每个面板的高度和宽度参数一致
    3、当点击其中一个面板时,遍历每一个被点击面板以上以及被点击的每个面板(tag值 <= 被点击面板tag值),其顶部位置=容器.顶部位置 + tag值×面板高度,得出每一个被点击面板上面的面板的位置。
    4、遍历每一个被点击面板以下的每个面板(tag值 > 被点击面板tag值),其顶部位置=容器.底部位置 - tag值×面板高度,得出每一个被点击面板下面的面板的位置。
    5、完毕。