UMG - Vertical/ScrollBox set child index

I’m trying to set the priority of a scrollbox that has some widget children.

Right now i want the new widget child to be at the top of the list, instead of the bottom, but I have no way of reversing the order of the scrollbox. I can’t also set the “order” (index) I want to add the child to.
Is there any function/panel I can use that let’s me organize it’s children?

Unfortunately no, never quite fixed this issue. Let me know if you happen to figure it out. I guess the only way atm I can think of is to have a function that removes and stores all the previous widgets adds the new one and then the saved ones but I ended up not using this in my game and just inverted the menu :frowning:

If you find the c++ code that allows to set the index let me know I may just do a custom node for it. I’ll look for it too

Did you ever find a solution? I would like to know too.

EDIT: At the moment I clear the box from all children after the point where I want to add the specific child. And then I recreate the children I had to delete. Given that widgets cannot be destroyed during a level, with this workaround I get quite an enormous number of unnecessary objects stacking in memory.

I would really like to be able to organize children via indexes in blueprint, exactly like you can do inside the editor with the arrows or dragging, or in c++.

Yes while you were writing I updated the original comment with this exact workaround…

oh, sorry I didn’t saw you changed your comment, but yea, I think “our” solution is the only one that I at least can think of, and I scrapped it exactly because it’s much more memory and processing consuming. Should definitely be a better way to do this, just an option in the widget that says where the children are added to would be enough

Well for my case I need to rearrange the order at runtime so I would need also the ability to set the index too.

I’m fairly sure you can do this via c++, and that it’s just a problem with the function not ported to blueprints. :frowning:

To be honest I haven’t actually looked.
I just guessed since you can do it from the editor using the arrows that appear when you select a child. It might be something only available in the umg editor though because I’m not finding anything. :frowning:

clearing the children and adding them again would likely work fine if instead of forgetting about them and recreating them you stored them in an array of widgets, adding them again based on the array you have, means any time you want to change the order you need to sort the array but you wouldn’t use a huge amount of memory as a result

Hello - it has been a while since you posted this, so I do not know if your problem has been solved. The C++ function that you are looking for is the UScrollBox::InsertChildAt function, which allows you to specify where you want it added.

That function unfortunately does not work correctly. Documentation says:

This does not update the live slate version, it requires a rebuild of the whole UI to see a change.

It is currently unknown how to “rebuild of the whole UI”.

Calling RebuildWidget and SynchronizeProperties on “this”, “the panel” and all the slots does nothing.

Ok, I know I’m approaching this several years later, but I figure I’ll explain my workaround, in case anyone else finds this page…

I’m assuming you have a container “YourContainer”
You’re gonna clone the Child references, then ClearChildren, then copy them back. Pretty lame, but it works.

void RefreshChildren()
{

 TArray<UWidget*> tempChildArray;
 for(int i = 0; i < YourContainer->GetChildrenCount(); i++)
 {
      tempChildArray.Add(YourContainer->GetChildAt(i));
 }
 YourContainer->ClearChildren();
 for(int i = 0; i < tempChildArray->GetChildrenCount(); i++)
 {
      YourContainer.AddChild(tempChildArray[i]);
 }

}

Hi I had the same problem I was trying to put an email list with the new emails at the top this is what I’ve used to solve the issue

I guess one can try and rebuild the engine from the source exposing these functions to blueprints.

	/**
	 * Swaps the child widget out of the slot, and replaces it with the new child widget.
	 * @param CurrentChild The existing child widget being removed.
	 * @param NewChild The new child widget being inserted.
	 * @return true if the CurrentChild was found and the swap occurred, otherwise false.
	 */
	virtual bool ReplaceChild(UWidget* CurrentChild, UWidget* NewChild);

	/**
	 * Inserts a widget at a specific index.  This does not update the live slate version, it requires
	 * a rebuild of the whole UI to see a change.
	 */
	UPanelSlot* InsertChildAt(int32 Index, UWidget* Content);

	/**
	 * Moves the child widget from its current index to the new index provided.
	 */
	void ShiftChild(int32 Index, UWidget* Child);

They are wrapped in the #if WITH_EDITOR for unknown reason. But probably you can snatch them out from that block.

Regarding the layout invalidation. Probably the necessary function is already exposed. It is InvalidateLayoutAndVolatility. Maybe exposing the functions and calling invalidate will do the trick.

I know this is an old post, but someone might find this helpful.
I know this approch is a tad hacky but it works well if you want all child widgets to be added to the top of a Vertical/scrollbox.

Set the Y scale of the scrollbox to -1 and do the same to the child widget. (the hacky bit)
Place the Scrollbox inside a vertical box and align to top.
Then after you add a child call scrollToEnd on the SB.

Done!