Речь идет не только о подписи обратного вызова, но и о том, как добавить обратный вызов.
Опция # 1: Использовать возвращаемое значение OnItemSelectionChanged (обратный вызов будет ограничен UObject)
В UListView
его член OnItemSelectionChanged
реализован с помощью макроса IMPLEMENT_TYPED_UMG_LIST
, который выполняет
virtual FOnItemSelectionChanged& OnItemSelectionChanged() const override { return OnItemSelectionChangedEvent; }
Таким образом, чтобы добавить функцию обратного вызова к делегату, используйте возвращаемое значение:
UCLASS()
class PROJECT_API UMyUserWidget : public UUserWidget
{
GENERATED_BODY()
void NativeConstruct() final
{
auto event = MyList->OnItemSelectionChanged();
event.AddUObject(this, &UMyUserWidget::MyEventCallback);
}
void MyEventCallback(UObject* e)
{
// implementation details, cast e to UMyListViewEntry*
}
// ...
};
Вы можете использовать только обратные вызовы, имеющие UObject*
в качестве параметра (UListView
- это специализация базовых классов с использованием UObject
в качестве типа записи).
Невозможно использовать делегата, который доступен в светокопии (BP_OnItemSelectionChanged
), поскольку он является личным.
Опция № 2: Определить пользовательский делегат
Если вы хотите использовать свой собственный тип записи непосредственно в качестве параметра в обратном вызове, вы можете либо
- реализовать свой собственный вид списка или
- происходит от
UListView
и вызывает пользовательский делегат в virtual void OnSelectionChangedInternal(UObject* FirstSelectedItem)
Хотя первый подход аналогичен реализации UListView
, второй подход очень короткий и может выглядеть как BP_OnItemSelectionChanged
:
DECLARE_MULTICAST_DELEGATE_TwoParams(FOnMyListItemSelectionChanged, UMyListViewEntry*, bool);
UCLASS(meta = (EntryInterface = UserObjectListEntry, EntryClass = UMyListViewEntry))
class PROJECT_API UMyListView : public UListView
{
GENERATED_BODY()
public:
FOnMyListItemSelectionChanged OnMyListItemSelectionChanged;
private:
void OnSelectionChangedInternal(UObject* FirstSelectedItem) override
{
Super::OnSelectionChangedInternal(FirstSelectedItem);
auto entry = Cast<UMyListViewEntry>(FirstSelectedItem);
OnMyListItemSelectionChanged.Broadcast(entry, entry != nullptr);
}
};
UCLASS()
class PROJECT_API UMyUserWidget : public UUserWidget
{
GENERATED_BODY()
void NativeConstruct() final
{
MyList->OnMyListItemSelectionChanged.AddUObject(this, &UMyUserWidget::MyEventCallback);
}
void MyEventCallback(UMyListViewEntry* e, bool isSelected)
{
// implementation details
}
private:
UPROPERTY(meta = (BindWidget), meta = (EntryClass = UMyListViewEntry))
UMyListView* MyList;
};