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
}