UWidget::SynchronizeProperties() 未在编辑器中调用 属性 更改

UWidget::SynchronizeProperties() is not being called on in editor property change

每次从小部件编辑器更改枚举变量 属性 时,我都必须更改子列表。

None 到目前为止我尝试过的功能似乎都有效(virtual void OnEndEditByDesigner(); virtual void PostEditChangeProperty(struct FPropertyChangedEvent & PropertyChangedEvent)).

SynchronizeProperties 文档指出

It can also be called by the editor to update modified state, so ensure all initialization to a widgets properties are performed here, or the property and visual state may become unsynced.

所以我不完全确定它是 use/overwrite 的正确函数(因为编辑器只能“可以”调用它来更新修改后的状态,不会在 属性编辑编辑)

下面是一些示例代码,展示了到目前为止我一直在尝试做的事情。

示例代码:

SampleButton.h

/* Includes */
#include "CoreMinimal.h"
#include "UObject/Object.h"
#include "Components/Button.h"
#include "Components/Image.h"
#include "Components/CanvasPanel.h"
#include "Components/ButtonSlot.h"
#include "Widgets/SOverlay.h"
#include "Components/Overlay.h"
#include "Components/TextBlock.h"
#include "Styling/SlateBrush.h"
#include "UUIW_MasterButton.generated.h"
//

UENUM(BlueprintType)
enum class EContentType : uint8 
{
    WithIcon,
    WithText,
}
class SAMPLE_API SampleButton : public UButton
{
    GENERATED_BODY()
public:
    UPROPERTY(EditAnywhere, BlueprintSetter=SetType, meta = (MakeEditWidget = ""))
        EContentType ContentType = EContentType::WithIcon;
    UPROPERTY(meta = (EditCondition = "ContentType == EContentType::WithIcon || ContentType == EContentType::WithTextAndIcon", EditConditionHides))
        UImage* Icon;
    UPROPERTY(meta = (EditCondition = "ContentType == EContentType::WithText || ContentType == EContentType::WithTextAndIcon", EditConditionHides))
        UTextBlock* TextBlock;

protected:
    virtual TSharedRef<SWidget> RebuildWidget() override;
    UOverlay* Overlay;
    virtual void SynchronizeProperties();
}

SampleButton.cpp

#include "UI/SampleButton.h"

TSharedRef<SWidget> SampleButton::RebuildWidget()
{
    Overlay = NewObject<UOverlay>();
    
    auto ButtonRef = Super::RebuildWidget();
    AddChild(Overlay);
    Icon = NewObject<UImage>();
    Icon->SetDisplayLabel(TEXT("Icon"));
    TextBlock = NewObject<UTextBlock>();
    TextBlock->SetDisplayLabel(TEXT("Text"));
    switch (ContentType)
    {
    case EContentType::WithIcon:
        Overlay->AddChild(Icon);
        break;
    case EContentType::WithText:
        Overlay->AddChild(TextBlock);
        break;
    case EContentType::WithTextAndIcon:
        Overlay->AddChild(Icon);
        Overlay->AddChild(TextBlock);
        break;
    }

    if ( GetChildrenCount() > 0 )
    {
        Cast<UButtonSlot>(GetContentSlot())->BuildSlot(MyButton.ToSharedRef());
    }

    return ButtonRef;

}

void UUUIW_MasterButton::SynchronizeProperties()
{
    Super::SynchronizeProperties();
    Overlay->ClearChildren();
    switch (ContentType)
    {
    case EContentType::WithIcon:
        Overlay->AddChild(Icon);
        break;
    case EContentType::WithText:
        Overlay->AddChild(TextBlock);
        break;
    case EContentType::WithTextAndIcon:
        Overlay->AddChild(Icon);
        Overlay->AddChild(TextBlock);
        break;
    }
}

Kinda 已经找到了解决方案。 PostEditChangeProperty(struct FPropertyChangedEvent & PropertyChangedEvent) 显然有效。但是它不是在值更改时调用,而是在之后调用蓝图编译(这就是为什么我认为它之前不起作用)