在虚幻引擎4中,我想将事件绑定到glcm31,glcm32,glcm33,glcm34
。该事件a10:a13
需要一个UListView::OnItemSelectionChanged
,所以我将一个指针传递给列表视图的列表条目类(我的自定义类来自FOnItemSelectionChanged
)作为参数。
NullableItemType
但是,IUserObjectListEntry
调用会导致错误
C2228:“ .__ Internal_AddDynamic”的左侧必须位于类/结构/联合中
所以我想我要绑定的回调函数(UCLASS()
class PROJECT_API UMyListViewEntry : public UUserWidget, public IUserObjectListEntry
{
GENERATED_BODY()
// Members and functions don't matter here.
};
UCLASS()
class PROJECT_API UMyUserWidget : public UUserWidget
{
GENERATED_BODY()
void NativeConstruct() final
{
MyList->OnItemSelectionChanged.AddDynamic(this, &UMyUserWidget::MyEventCallback);
}
void MyEventCallback(UMyListViewEntry* e)
{
// implementation details
}
private:
UPROPERTY(meta = (BindWidget))
UListView* MyList;
};
)的签名是错误的。
应该绑定到AddDynamic()
的函数的正确签名是什么?
答案 0 :(得分:0)
这不仅与回调的签名有关,而且与如何添加回调有关。
在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
)中可用的委托是私有的,因此无法使用。
如果您想直接在回调中使用自定义条目类型作为参数,则可以
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;
};