C++ Adding Widget to WidgetTree doesn't update Hierarchy view in editor

Thanks’ for uncovering this guide!

I have encounter an issue however when i call FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified. This causes a hard crash about a second later during widget repaint from ChildrenBase.h -> Debug_TestDestroyTag() with the message: “The FChildren is destroyed. You probably have 1 widget owned by 2 different FChildren.”

The crash happens regardless of whether I actually make modifications or just set the flags.

I’ve not been able to determine where/why. Did you encounter anything similar or have any ideas?

Update: Added example code that works correctly on a custom User Widget, but causes a crash when that custom user widget is included in another custom user widget via the other widgets named slot.

void UDevHelpBPFL::RemoveChild_Editor(UWidget* parent, UWidget* child) {
#if WITH_EDITOR
	//https://forums.unrealengine.com/t/c-adding-widget-to-widgettree-doesnt-update-hierarchy-view-in-editor/361258/13
	//https://unreal-garden.com/tutorials/build-widgets-in-editor/
	if (IsValid(parent) && IsValid(child)) {

		//Walk the hirearchy till reaching the root User Widget
		UObject* root = parent;
		while (true) {
			UObject* currentWidgetTree = root->GetOuter();
			UObject* treeOuter = currentWidgetTree ? currentWidgetTree->GetOuter() : nullptr;
			if (treeOuter && treeOuter->IsA<UUserWidget>()) {
				root = treeOuter;
			} else {
				// Reached top level widget.
				break;
			}
		}

		UUserWidget* rootWidget = Cast<UUserWidget>(root);
		if (rootWidget == nullptr) {
			return;
		}
		
		UWidgetBlueprintGeneratedClass* wbpClass = Cast<UWidgetBlueprintGeneratedClass>(rootWidget->GetClass());

		UWidgetBlueprint* asset = Cast<UWidgetBlueprint>(wbpClass->GetPackage()->FindAssetInPackage());

		//Gain reference to the tree root and flag it as modified.
		UWidget* treePanelRoot = asset->WidgetTree->FindWidget(root->GetFName());
		if (treePanelRoot != nullptr) {
			treePanelRoot->Modify();
		}

		//Gain reference to the child in the tree and modigy it.
		UWidget* treePanelChild = asset->WidgetTree->FindWidget(child->GetFName());
		if (treePanelChild != nullptr) {
			treePanelChild->RemoveFromParent();
			treePanelChild->Modify();
		}

		//Mark asset as having been modified including structurally
		asset->Modify();
		FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(asset);
	}
#endif
}