Мне нужно изменить порядок TObjectList в соответствии с некоторыми правилами. Как я могу этого добиться?
Поэтому я динамически добавляю панели в ScrollBox. Когда я добавляю их, я также добавляю их в ObjectList в том порядке, в котором они добавляются во время выполнения, для будущего использования. Затем я могу реорганизовать панели в scrollBox путем перетаскивания. Я хочу, чтобы 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, фактические объекты освобождаются, поэтому второй 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 порядок тот же, что и раньше...
Опять же, я хочу иметь возможность упорядочивать ObjectList в соответствии с порядком панелей из scrollBox. В процедуре повторного заказа я фактически получаю все панели в желаемом порядке. Мне просто нужно, чтобы они были в том же порядке в моем ObjectList.
Есть ли другой способ сделать это? Другое дело, что я создал новый класс, который будет содержать индекс рядом с TPanel и использовать его в ObjectList для поддержания порядка?