Slate ActorComponent Picker ComboBox (for Components on Current Actor)

kept getting hit with an edge case which I just can’t figure out.
the progress so far
ActorComponentPicker.h
went with FComponentReference to get native support for nullptr inside OptionSource(), and an attempt to “fix” the edge case (technically my primary reason, but that is later). Never got around to implementing the ActorPicker+ComponentPicker, for a 100% replacement on the Editors default ActorComponentPicker.

#pragma once

#include "CoreMinimal.h"
#include "IPropertyTypeCustomization.h"
#include "IPropertyUtilities.h"

/**
 * Allows for selecting from the list of ActorComponents of type T on the current Actor.
 * supports filtering for derivatives of UActorComponent through defining T
 */
class RUINSGAMEEDITOR_API FActorComponentPicker : public IPropertyTypeCustomization
{
public:
	static TSharedRef<IPropertyTypeCustomization> MakeInstance() { return MakeShared<FActorComponentPicker>(); }

	virtual void CustomizeHeader(TSharedRef<IPropertyHandle> PropertyHandle, FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& CustomizationUtils) override;
	virtual void CustomizeChildren(TSharedRef<IPropertyHandle>, IDetailChildrenBuilder&, IPropertyTypeCustomizationUtils&) override {}

private:
	// natively
	TArray<TSharedPtr<FComponentReference>> Items;
	TWeakObjectPtr<AActor> currentActor;

	TArray<TSharedPtr<FComponentReference>> CollectComponents(TSharedRef<IPropertyHandle> PropertyHandle, UClass* RequiredClass) const;
	TSharedRef<SWidget> OnGenerateWidget(TSharedPtr<FComponentReference> Item) const;
	void OnSelectionChanged(TSharedPtr<FComponentReference> NewValue, ESelectInfo::Type, TSharedRef<IPropertyHandle> PropertyHandle);
	FText GetCurrentSelectionText(TSharedRef<IPropertyHandle> PropertyHandle) const;
};

ActorComponentPicker.cpp

#include "ActorComponentPicker.h"
#include "DetailWidgetRow.h"

void FActorComponentPicker::CustomizeHeader(TSharedRef<IPropertyHandle> PropertyHandle, FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& CustomizationUtils)
{
	FObjectPropertyBase* ObjProp = CastField<FObjectPropertyBase>(PropertyHandle->GetProperty());
	if ( !ObjProp || !ObjProp->PropertyClass->IsChildOf(UActorComponent::StaticClass()) )
	{
		HeaderRow.NameContent()[PropertyHandle->CreatePropertyNameWidget()];
		HeaderRow.ValueContent()[PropertyHandle->CreatePropertyValueWidget()];
		return;
	}
	UClass* RequiredClass = ObjProp->PropertyClass;

	TArray<UObject*> OuterObjects;
	PropertyHandle->GetOuterObjects(OuterObjects);

	AActor* OwnerActor = nullptr;
	if ( OuterObjects.Num() == 1 )
	{
		if ( AActor* A = Cast<AActor>(OuterObjects[0]) ) { OwnerActor = A; }
		else { OwnerActor = OuterObjects[0]->GetTypedOuter<AActor>(); }
	}

	if ( OwnerActor == nullptr ) { return; }
	currentActor = OwnerActor;

	Items.Reset();
	Items = CollectComponents(PropertyHandle, RequiredClass);

	if ( Items.Num() <= 1 )
	{
		HeaderRow.NameContent()[PropertyHandle->CreatePropertyNameWidget()];
		HeaderRow.ValueContent()[PropertyHandle->CreatePropertyValueWidget()];
		return;
	}

	HeaderRow.NameContent()[PropertyHandle->CreatePropertyNameWidget()].ValueContent()
	[
		SNew(SVerticalBox)
		+SVerticalBox::Slot().AutoHeight()
		[
			SNew(SHorizontalBox)
			+SHorizontalBox::Slot().AutoWidth().Padding(0,0,4,0) [ SNew(STextBlock).Text(FText::FromString(TEXT("ThisActor"))) ]
			+SHorizontalBox::Slot().AutoWidth()
			[
				SNew(SComboBox<TSharedPtr<FComponentReference>>)
				.OptionsSource(&Items)
				.OnGenerateWidget(this, &FActorComponentPicker::OnGenerateWidget)
				.OnSelectionChanged( SComboBox<TSharedPtr<FComponentReference>>::FOnSelectionChanged::CreateSP( this, &FActorComponentPicker::OnSelectionChanged, PropertyHandle))
				[
					SNew(STextBlock)
					.Text_Lambda([this, PropertyHandle]()
					{
						return GetCurrentSelectionText(PropertyHandle);
					})
				]
			]
		]
		+SVerticalBox::Slot()[ PropertyHandle->CreatePropertyValueWidget() ]
	];
}

TArray<TSharedPtr<FComponentReference>> FActorComponentPicker::CollectComponents(TSharedRef<IPropertyHandle> cPH, UClass* RequiredClass) const
{
	TArray<TSharedPtr<FComponentReference>> Result;
	Result.Add(MakeShared<FComponentReference>()); // None
	
	TArray<UActorComponent*> Components;
	currentActor->GetComponents(Components);

	for ( UActorComponent* Comp : Components )
	{
		if ( Comp == nullptr || (Comp->IsA(RequiredClass) == false) ) { continue; }
		TSharedPtr<FComponentReference> Item = MakeShared<FComponentReference>();
		Item->ComponentProperty = Comp->GetFName();
		Item->OtherActor = currentActor.Get();

		Result.Add(Item);
	}
	return Result;
}

TSharedRef<SWidget> FActorComponentPicker::OnGenerateWidget(TSharedPtr<FComponentReference> Item) const
{
	FString str = (Item.IsValid() == false || Item->ComponentProperty.IsNone()) ? TEXT("None") : (Item->ComponentProperty).ToString();
	return SNew(STextBlock).Text(FText::FromString(str));
}

void FActorComponentPicker::OnSelectionChanged(TSharedPtr<FComponentReference> Selected, ESelectInfo::Type, TSharedRef<IPropertyHandle> cPH)
{
	if ( Selected.IsValid() == false || currentActor == nullptr )
	{
		UE_LOG(LogTemp, Error, TEXT("Invalid state in OnSelectionChanged"));
		return;
	}
	// I just can't get this to work; it is supposed to be for undo/redo, but that works anyways, so...
//	const FScopedTransaction Tx(LOCTEXT("ComponentPicker", "Assigning Component"));
	cPH->NotifyPreChange();

	UActorComponent* Component = nullptr;

	FPropertyAccess::Result
	Result = cPH->SetValueFromFormattedString(Selected->ComponentProperty.ToString());
	// this is only used for special cases, and those working has a list of requirements.
	if ( Result != FPropertyAccess::Success )
	{
		UE_LOG(LogTemp, Warning, TEXT("First Attempt Fail"));
		if ( !Selected->ComponentProperty.IsNone() ) { Component = Selected->GetComponent(currentActor.Get()); }
		Result = cPH->SetValue(Component);
		// this is rare, and almost never fired.
		if ( Result != FPropertyAccess::Success ) { UE_LOG(LogTemp, Error, TEXT("Failed both")); }
	}
/*
	UE_LOG(LogTemp, Warning, TEXT("assigning component to actor %s, on property %s, of type %s, with object %s, resultantComp %s")
		, *(currentActor != nullptr ? currentActor->GetName() : TEXT("none"))
		, *cPH->GetProperty()->GetName()
		, *cPH->GetProperty()->GetClass()->GetName()
		, *Selected->ComponentProperty.ToString()
		, *(Component != nullptr ? Component->GetName() : TEXT("None"))
	);
*/
	cPH->NotifyPostChange(EPropertyChangeType::ValueSet);
	cPH->NotifyFinishedChangingProperties();
}

FText FActorComponentPicker::GetCurrentSelectionText(TSharedRef<IPropertyHandle> cPH) const
{
	UObject* Value = nullptr;
	if ( cPH->GetValue(Value) != FPropertyAccess::Success ) { return FText::FromString("None"); }
	if ( UActorComponent* Comp = Cast<UActorComponent>(Value) ) { return FText::FromName(Comp->GetFName()); }
	return FText::FromString("None");
}

this works in most cases, and is fine.

unresolved Edge Case:
when the WeakObjectPtr resides inside a struct, and the object being assigned to the pointer is a Blueprint instantiated component. effectively the Editor doesn’t know whether to choose the Object inside the Blueprint, or the one that is on that in-Level-Instance.
there is also a name collision issue on the fallback if the name is too short, but even trying to correct with longer random character names still results in a collision of 2, meaning it is still confused whether to use the Blueprint instantiated object, or the one on the in-Level-Instance.