Create a dynamic Button with C++

Hello,

i struggle at the moment with the umg c++ and the UE documentation is not realy helpful.

I want to create a dynamic button list and want to give any button a dynamic name and event. So i created a widget with a with a ListView and include the entry Widget WBP_Replay.

My WBP_Replay has:

SizeBox
  Button called ReplayButton and is set as Variable
    Text called ReplayText and is set as Variable

I created a C++ Class for the Replaywidget and changed the parent from WBP_Replay

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "Components/TextBlock.h"
#include "Components/Button.h"
#include "ReplayWidget.generated.h"

/**
 * 
 */
UCLASS()
class ALVANIAN_API UReplayWidget : public UUserWidget
{
	GENERATED_BODY()
	
	public:

	UPROPERTY(BlueprintReadWrite, meta = (BindWidget))
	class UTextBlock* ReplayText;

	UPROPERTY(BlueprintReadWrite, meta = (BindWidget))
	class UButton* ReplayButton;
};

now, i want to fill the List with the Buttons, but i can add a Button but not change the Text or add a Event on this.

	if(!Dialog->IsInViewport())
	{
		Dialog->AddToViewport();
	}

	UReplayWidget* NewReplay = CreateWidget<UReplayWidget>(GetWorld(),ReplayWidgetClass);
	if(IsValid(NewReplay))
	{
		NewReplay->ReplayText->SetText(FText::FromString(TEXT("Make light red.")));
		NewReplay->ReplayButton->OnClicked.AddDynamic(this, &ULightControllerComponent::RedLight);
		Dialog->Replays->AddItem(NewReplay);
	}

In my Dialog Widget, the Button has the default Text. when i print the Text from this button, than it has the Text i set

    FString Text = *NewReplay->ReplayText->GetText().ToString();
    D( (TEXT("Text: %s"), Text) );  // -> Make light red

i addet a OnClicked Event on the Button himself.

void UReplayWidget::NativeConstruct()
{
    if(ReplayButton)
    {
        ReplayButton->OnClicked.AddDynamic(this, &UReplayWidget::OnClick);
    }
}

void UReplayWidget::OnClick()
{
    UE_LOG(LogTemp, Warning, TEXT("Button Text is: %s "),*ReplayText->GetText().ToString());
}

This event return the default value.

It’s like two different Buttons, the C++ Button is not the Button in the Widget. What did i Wrong and how can i solve this?

Thanks

has anyone an idea? I’m really stuck.

need still help

My results so far:

The added button is definitely not the button I created.

I created the button with a clear name:

UReplayWidget* NewReplay = CreateWidget<UReplayWidget>(GetWorld(),ReplayWidgetClass, TEXT("TestButton");

and added him to the List

Dialog->Replays->AddItem(NewReplay);

When i Ask the Name of the Button with

NewReplay->GetName();

a got “TestButton”

I added the following line to the On Clicked Event on the button himself:

UE_LOG(LogTemp, Warning, TEXT("Button Name is: %s "),*GetName());

on click i got a generic Name: "LogTemp: Warning: Button Name is: BP_W_Replay_C_0 "

If I get the button directly from the list array, then I have the completely correct name again.

TArray<UObject*> ReplayList = Dialog->Replays->GetListItems();
D(ReplayList[0]->GetName());

i got “TestButton”

D:

#define D(x) if(GEngine){GEngine->AddOnScreenDebugMessage(-1, 2.0f, FColor::Yellow, x);}

The ListView in DialogWidget:

UPROPERTY(BlueprintReadWrite, meta = (BindWidget))
class UListView* Replays;

with ReplayList.Num() i got 1.

My button is correctly added to the ViewList. I can get him from the ViewList. There is also no other button in the ViewList. But on the display a completely new button is inserted, which is based on the same class but not the button I added. It also doesn’t show up in the list.

Why is this happening? Am I not understanding an Unreal Engine behavior?