Changing the z-order of controls (Views: 100)


How to move a control just one position within the z-order of the parent.


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.



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);
  I, Curr: Integer;
  Control: TControl;
  List: TList;
  if Sender is TControl then
    // sender is an control
    Control := Sender as TControl;
    // check for parent control, managing the z-order
    if Control.Parent = nil then
      // not available
    // get position of the sender
    Curr := -1;
    for I := 0 to Pred(Control.Parent.ControlCount) do
      if Control.Parent.Controls[I] = Sender then
        Curr := I;
    if Curr < 0 then
      // hm, position not found
    List := TList.Create;
      if MoveUp then
        for I := Curr + 2 to Pred(Control.Parent.ControlCount) do
          // get the other controls, to be moved, too
        // bring sender to front
        for I := 0 to Pred(List.Count) do
          // move the remaining controls
        for I := 0 to Curr - 2 do
          // get the other controls, to be moved, too
        // send sender to back
        for I := Pred(List.Count) downto 0 do
          // move the remaining controls

<< Back to main page