How to pass self-reference to UButton's OnClicked delegate (UMG)?

ButtonText is a UTextBlock variable in the header of UExtendedButton, if you want it to be there. If you have added TextBlock in UMG-editor, then it should be there by default. Double check Appearence and Behavior categories, e.g., it could be white text on white background or text could have 0 alpha.

1 Like

I’ve tried to create a custom OnClicked delegate for custom Button (inherited from UButton), that passes self-reference, but it is not exectued when I click a button.

Header:

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnButtonClickedRefDelegate, UExtendedButton*, ButtonRef);
    UCLASS()
    class DQS_API UExtendedButton : public UButton
    {
    	GENERATED_UCLASS_BODY()
    	
    public:
    	UExtendedButton();
    
    	/** Should be called when the button is clicked, also gives the reference to this... */
    	UPROPERTY(BlueprintAssignable, Category = "Button|Event")
    	FOnButtonClickedRefDelegate OnClickedReferenced;
    
    	UFUNCTION()
    	void OnSelfClicked();
    
    	UFUNCTION()
    	void DoSomething(UExtendedButton* ButtonRef);
    
    protected:
    	/** Handle the actual click event from slate and forward it on */
    	FReply SlateHandleClicked();
    
    };

Source:

UExtendedButton::UExtendedButton(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	OnClickedReferenced.AddDynamic(this, &UExtendedButton::DoSomething);
	OnClicked.AddDynamic(this, &UExtendedButton::OnSelfClicked);

	
}

void UExtendedButton::OnSelfClicked()
{
	if (GEngine)
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, 
			FString("Hello :: ").Append(this->ButtonText->GetText().ToString())
		);

	OnClickedReferenced.Broadcast(this);
}
void UExtendedButton::DoSomething(UExtendedButton* ButtonRef)
{
	OnClickedReferenced.Broadcast(ButtonRef);

	if (GEngine)
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red,
			FString("Do :: ").Append(ButtonRef->ButtonText->GetText().ToString())
		);
}

/* Cannot be overwritten since the original one isn't virtual... */
FReply UExtendedButton::SlateHandleClicked()
{
	OnClickedReferenced.Broadcast(this);

	return FReply::Handled();
}

I couldn’t set things right as in [here][1], since I didn’t expect to touch Slate at all, only UMG.
What I want to achieve is this BP working:

Solved it.
In UButton we have RebuildWidget(), which we should override for custom OnClicked. We are interested in MyButton = SNew(SButton) .OnClicked(BIND_UOBJECT_DELEGATE(FOnClicked, SlateHandleClicked))... , in which SlateHandleClicked should be OnClickedReferenced.Broadcast(this) instead of original one OnClicked.Broadcast(). To do it, I suppose, we need to have all the SlateHandle-functions (Clicked, Pressed, Hovered, etc.) implemented once more, or just to rewrite engine’s functions to be virtual.

The complete code for RebuildWidget(), ( SlateHandleClicked() stays the same as in the question post):

TSharedRef<SWidget> UExtendedButton::RebuildWidget()
{
	MyButton = SNew(SButton)
		.OnClicked(BIND_UOBJECT_DELEGATE(FOnClicked, SlateHandleClicked))
		.OnPressed(BIND_UOBJECT_DELEGATE(FSimpleDelegate, SlateHandlePressed))
		.OnReleased(BIND_UOBJECT_DELEGATE(FSimpleDelegate, SlateHandleReleased))
		.OnHovered_UObject(this, &UExtendedButton::SlateHandleHovered) /* Be careful here... */
		.OnUnhovered_UObject(this, &UExtendedButton::SlateHandleUnhovered) /* And here... */
		.ButtonStyle(&WidgetStyle)
		.ClickMethod(ClickMethod)
		.TouchMethod(TouchMethod)
		.IsFocusable(IsFocusable)
		;

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

	return MyButton.ToSharedRef();
}

i have been using your code snippet and did implement it in my project. but no child umg under this specific Umg class is not getting rendered. as u can see in this video:

any idea?

nad thanks for the code snippets

You need to add initialisation in constructor UExtendedButton::UExtendedButton like ButtonText = CreateDefaultSubobject(_T("ButtonText"));.

not sure where this ButtonText coming from . but anyway thanks.

it turned out to be a issue caused by RebuildWidget(). now fixed

What do you mean?

Hello! I’ve tride this method, but in runtime I catch an error, if I use RebuildWidget function. I’ve implemented all methods such as onclicked, onhoverd etc. What can be wrong here?

It would be easier if I can replicate the particular issue. Can you share the code?
If it’s still relevant, though.

Thank you! I’ve already done with it. Just needed to implement all virtual methods including onhover etc. I ignored them first because I didn’t need them. And when I implemented them, the errors disappeared.

Glad to hear that. Have a nice day then.

Thanks, and you too, man!