"Use selected asset from content browser" allows WBP with incorrect interface to be selected in UListView

tldr; UListViewBase has “MustImplement = “/Script/UMG.UserListEntry”” as a UPROPERTY meta tag on EntryWidgetClass which means the property edit field in sub classes (eg. CommonListView) don’t always enforce the correct required interface check.

We’ve run into a situation where the “Use Selected Asset from Content Browser” can be used on the CommonListView to force an invalid asset to be used which can cause subtle bugs that can be tricky and time consuming to track down. This is partly an education issue on our behalf so developers know what they need to do to correctly use a CommonListView, but there is an editor bug that is allowing invalid workflows to “mostly work”.

CommonListView and ListView both require that widgets implement the UserObjectListEntry interface before they show as an option in the “Entry Widget Class” drop down. UListViewBase only requires widgets implement the UserListEntry interface. (The fact they are named so similarly was also a source of confusion for us, but not what I’m here to talk about)

* If the selected widget in the content browser doesn’t implement either interface then the “Use Selected Asset from Content Browser” button will not do anything -> Correct

* If the selected widget in the content browser implements UserObjectListEntry interface then the “Use Selected Asset from Content Browser” button will insert that widget as the selected entry -> Correct

* If the selected widget in the content browser implements UserListEntry interface then the “Use Selected Asset from Content Browser” button will insert that widget as the selected entry -> Wrong

This appears correct in some ways because the list will create the widget at both design time and game time, but other features won’t work. For example, if you enable the Viewmodel Extension it won’t correctly populate the list with the view models used by the selected widget causing confusion about why not.

I tried to track down the fix but I wasn’t able to get to the bottom of it, but got some ideas.

* PropertyHandleImpl.cpp -> FPropertyHandleObject::SetObjectValueFromSelection

This function checks for “GetClassMetaData(TEXT(“MustImplement”))” but it returns UserListEntry, not UserObjectListEntry. I believe this is because UListViewBase defines the member and sets the “MustImplement” meta tag to “/Script/UMG.UserListEntry” but then derived classes (eg. CommonListView) don’t report that the new interface to require is UserObjectListEntry.

I’m not sure how to resolve this at this point so I was hoping to pass this along and maybe someone knows off the top of their head how to resolve. This isn’t a major issue for us, but due to some knowledge gaps there have been some incorrect work patterns that have snuck in that we’re trying to get out and this bug caused those patterns to semi-legitimise themselves.

[Attachment Removed]

Steps to Reproduce
* Create a new WidgetBlueprint (“WBP_A”)

* Implement the UserListEntry interface

* Select “WBP_A” in the content browser

* Add a CommonListView to a different blueprint

* Click into the drop down -> Notice that “WBP_A” isn’t listed

* Click the “Use Selected Asset from Content Browser” button -> Notice that “WBP_A” was forced to be selected

[Attachment Removed]

Hi [mention removed]​,

Sorry about the delay. I was just assigned this ticket now. I will look into it now and should get back to you soon.

Best,

Francisco

[Attachment Removed]

Hi [mention removed]​,

Thanks for the clear repro steps. I’ve confirmed this behavior both in the UE 5.6 launcher build and a recent source build from Main (CL 49537288). This does appear to be an editor-side validation inconsistency between the Entry Widget Class dropdown filtering and the “Use Selected Asset from Content Browser” assignment path.

I’m going to dig into this a bit further on the engine side and will follow up soon.

Best,

Francisco

[Attachment Removed]

Hello [mention removed]​,

This does appear to be an engine-side inconsistency, and I’ve filed it as an engine bug. I was able to reproduce the behavior locally in both UE 5.6 (Launcher) and UE5-Main. Once the issue becomes publicly visible, it should be available here: Unreal Engine Issues and Bug Tracker (UE\-359502)

In the meantime, as a workaround, you can add an editor-only validation guard in UCommonListView::PostEditChangeProperty to clear EntryWidgetClass when the assigned widget does not implement UserObjectListEntry. This prevents the invalid configuration from persisting even if it’s assigned via “Use Selected Asset From Content Browser”:

#if WITH_EDITOR
void UCommonListView::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
	Super::PostEditChangeProperty(PropertyChangedEvent);
 
	static const FName EntryWidgetClassName =
		GET_MEMBER_NAME_CHECKED(UListViewBase, EntryWidgetClass);
 
	if (PropertyChangedEvent.Property &&
		PropertyChangedEvent.Property->GetFName() == EntryWidgetClassName)
	{
		if (EntryWidgetClass &&
			!EntryWidgetClass->ImplementsInterface(UUserObjectListEntry::StaticClass()))
		{
			UE_LOG(LogTemp, Warning,
				TEXT("CommonListView EntryWidgetClass must implement UserObjectListEntry. Resetting invalid class '%s'."),
				*EntryWidgetClass->GetName());
 
			EntryWidgetClass = nullptr;
		}
	}
}
#endif

Please let me know if this information is helpful.

Best,

Francisco

[Attachment Removed]

Thanks. I tested this and it worked, but I had to make a minor change.

static const FName EntryWidgetClassName = GET_MEMBER_NAME_CHECKED(UListViewBase, EntryWidgetClass); -> static const FName EntryWidgetClassName = GetEntryWidgetClassPropertyName();

This threw an error saying “EntryWidgetClass” was not accessible. I looked at other usages of the “GET_MEMBER_NAME_CHECKED” macro and copied the pattern where a “GetXYZPropertyName” function was added to the appropriate class (in this instance, UListViewBase). After doing that and calling that function it all worked.

I also ended up moving that function into UListView because that is the first class to change the required interface for the entry widget and anything deriving from that should inherit this change.

[Attachment Removed]

Hello [mention removed]​,

Glad to hear the workaround is working on your end. Thanks for the adjustment, your change is definitely appropiate. This should be a good temporary fix until the issue is addressed.

I’ll go ahead and close this case now.

Best,

Francisco

[Attachment Removed]