Changing the z-order of controls (Views: 709)
Problem/Question/Abstract: How to move a control just one position within the z-order of the parent. Answer: The default methods Usually you can bring any control on a form to front or send it to the back using the methods supplied with the TControl class. AnyControl.BringToFront; AnyControl.SendToBack; However, often these methods will not suffice. If you want to move the control just one position, there are no public methods to acompolish just this. In the private section of the TControl-class you find the method SetZOrderPosition which you cannot use. Looking at the source code, you'll notice, you cannot even cut-n-copy that, as it is accessing some private variables/objects, which are not made public either. A simple solution The solution, to work around this limitation, is to move the control either to the top or the back and move the others, that should remain in front (or behind), too. The following procedure will do just this. The first parameter Sender takes the control to be moved. The second paramter points the direction. True will bring it to front, False will move it to the back. procedure ChangeControlZOrder(Sender: TObject; MoveUp: Boolean = True); var I, Curr: Integer; Control: TControl; List: TList; begin if Sender is TControl then begin // sender is an control Control := Sender as TControl; // check for parent control, managing the z-order if Control.Parent = nil then // not available Exit; // get position of the sender Curr := -1; for I := 0 to Pred(Control.Parent.ControlCount) do if Control.Parent.Controls[I] = Sender then begin Curr := I; Break; end; if Curr < 0 then // hm, position not found Exit; List := TList.Create; try if MoveUp then begin for I := Curr + 2 to Pred(Control.Parent.ControlCount) do // get the other controls, to be moved, too List.Add(Control.Parent.Controls[I]); // bring sender to front Control.BringToFront; for I := 0 to Pred(List.Count) do // move the remaining controls TControl(List[I]).BringToFront; end else begin for I := 0 to Curr - 2 do // get the other controls, to be moved, too List.Add(Control.Parent.Controls[I]); // send sender to back Control.SendToBack; for I := Pred(List.Count) downto 0 do // move the remaining controls TControl(List[I]).SendToBack; end; finally List.Free; end; end; end; |