いくつかの規則に従って、TObjectList の順序を変更する必要があります。どうすればこれを達成できますか?
したがって、ScrollBox に動的にパネルを追加します。それらを追加するときは、将来の使用のために、実行時に追加される順序で ObjectList にも追加します。次に、スクロール ボックス内のパネルをドラッグ アンド ドロップで再編成できます。ドラッグ/ドロップによって実行時に設定されるのと同じ順序を ObjectList に反映させたいと思います。
これが私のコードです:
var
MainForm: TMainForm;
PanelList,PanelListTMP:TObjectList;
implementation
...
procedure TMainForm.FormCreate(Sender: TObject);
begin
PanelList:=TObjectList.Create;
PanelListTMP:=TObjectList.Create;
end;
procedure TMainForm.Button1Click(Sender: TObject);
begin
AddPanel('0');
AddPanel('1');
AddPanel('2');
AddPanel('3');
AddPanel('4');
end;
procedure TMainForm.Addpanel(what:string);
var
pan:TPanel;
bv:TShape;
begin
pan:=TPanel.Create(self);
pan.Parent:=TheContainer;
pan.Height:=50;
pan.BevelOuter:=bvNone;
pan.BorderStyle:=bsNone;
pan.Ctl3D:=false;
pan.Name:='LayerPan'+what;
pan.Caption:=what;
pan.Align:=alBottom;
pan.OnMouseDown:=panMouseDown;
end;
procedure TMainForm.panMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
var
i:integer;
idu:String;
panui:TPanel;
begin
panui:=Sender as TPanel;
panui.ParentColor:=false;
panui.BringToFront;
// DRAG DROP STUFF
ReleaseCapture;
panui.Perform(wm_nclbuttondown,HTCAPTION,0);
for i := 0 to MainForm.ComponentCount - 1 do
begin
if MainForm.Components[i] is TWinControl then
if TWinControl(MainForm.Components[i]) is TPanel then
if (TWinControl(MainForm.Components[i]) as TPanel).Parent=MainForm.TheContainer then
begin
(TWinControl(MainForm.Components[i]) as TPanel).Align:=alBottom;
end;
end;
TheContainer.ScrollInView(panui);
ReOrderPanels;
end;
Procedure TMainForm.ReOrderPanels;
begin
end;
ReOrderPanels プロシージャで何をすればよいですか? ScrollBox のパネルを下から上に新しい TObjectList (PanelListTMP) にフィードし、PanelList をクリアして PanelListTMP から再度追加することを考えていましたが、それを行うとエラーが発生します: アクセス違反、および EInvalidPointer - 無効なポインター操作
だからこれは私が考えたことです:
procedure TMainForm.ReOrderPanels;
var
ctrl:TControl;
pos:TPoint;
pan:TPanel;
bad:boolean;
ord,i:integer;
begin
memo2.Lines.Add('*** new order START');
panelListTMP.Clear;
// scroll top
TheContainer.VertScrollBar.Position := 0;
// scroll down
TheContainer.VertScrollBar.Position := TheContainer.VertScrollBar.Range;
// get panel
Pos:=TheContainer.ClientOrigin;
Pos.Y:=Pos.Y+TheContainer.Height-5;
ctrl := FindVCLWindow(pos) ;
if ctrl is TPanel then
if TPanel(ctrl).Parent = TheContainer then
begin
pan:=(ctrl as TPanel);
panelListTMP.Add(pan);
end;
ord:=1;
bad:=false;
repeat
repeat
Pos.Y:=pos.Y-1;
until (FindVCLWindow(pos) is TPanel)and(FindVCLWindow(pos)<>pan);
if (FindVCLWindow(pos) is TPanel)and(FindVCLWindow(pos).Name<>'LayerPan') then
begin
pan:=FindVCLWindow(pos) as TPanel;
containeru.VertScrollBar.Position := 0;
containeru.ScrollInView(pan);
ord:=ord+1;
panelListTMP.Add(pan);
end
else
bad:=true;
until bad=true;
// and now I do the swap between the ObjectLists...
panelList.Clear;
for i:=0 to PanelListTMP.Count-1 do
begin
(PanelListTMP.Items[i] as TPanel).Parent:=containeru;
panelList.Add(PanelListTMP.Items[i]);
end;
end;
したがって、ObjectList は実際のオブジェクトへのポインターを格納しているため、最初の ObjectList をクリアすると、実際のオブジェクトが解放されるため、2 番目の ObjectList には実行できなくなったポインターのリストが含まれていると思います...私は私が望むものを達成しますか?
したがって、ButtonClick では、次の順序でパネルを含む ObjectList を取得します。
PanelList[0] - Panel0
PanelList[1] - Panel1
PanelList[2] - Panel2
PanelList[3] - Panel3
PanelList[4] - Panel4
ScrollBox 内にパネルをドラッグ アンド ドロップした後、(ScrollBox 内で) このような順序になる可能性があります。
Panel3
panel1
Panel4
Panel2
Panel0
しかし、ObjectList では、順序は以前と同じです...
繰り返しますが、scrollBox からのパネルの順序に従って ObjectList を順序付けできるようにしたいと考えています。再注文手順では、実際にすべてのパネルを希望の順序で取得します。ObjectList で同じ順序にする必要があるだけです。
これを行う他の方法はありますか?他に、TPanel の横にインデックスを保持し、それを ObjectList で使用して順序を維持する新しいクラスを作成しますか?