Download

Customizing a scrollbar in ListView widget

Hello there,
I would like to ask somebody or Epic’s developers about adding possibility to customize the scrollbar in ListView like it’s realized in ScrollBox. Maybe I miss something and there is a way to do this… I’ll glad to any help!

Hey there, did you find a way to do this?

1 Like

Hi
I had the same problem, we wanted to customize the design of the ScrollBar.
And because we’re not using a modified Engine version, I had to find a workaround. I created a child that hold a BarStyle value, and update the ScrollBar widget right after the construction of the widget.

#pragma once

#include "CoreMinimal.h"
#include "Components/ListView.h"
#include "CustomListView.generated.h"

/**
 * 
 */
UCLASS()
class TEST_API UCustomListView : public UListView
{
	GENERATED_BODY()

	UCustomListView(const FObjectInitializer& Initializer);

protected:
	virtual TSharedRef<STableViewBase> RebuildListWidget() override;

public:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Style", meta = (DisplayName = "Bar Style"))
	FScrollBarStyle WidgetBarStyle;
};
#include "UI/CustomListView.h"

#include "UI/SCustomListView.h"

UCustomListView::UCustomListView(const FObjectInitializer& Initializer)
	:Super(Initializer)
{
	WidgetBarStyle = FCoreStyle::Get().GetWidgetStyle<FScrollBarStyle>("Scrollbar");
}

TSharedRef<STableViewBase> UCustomListView::RebuildListWidget()
{
	auto outRef = ConstructListView<SCustomListView>();
	auto customViewRef = StaticCastSharedRef<SCustomListView<UObject*>>(outRef);
	
	customViewRef->UpdateBarStyle(WidgetBarStyle);
	
	return outRef;
}
#pragma once

#include "Widgets/Views/SListView.h"

#include "CoreMinimal.h"
#include "Widgets/SCompoundWidget.h"

/**
 * 
 */
template <typename ItemType>
class TEST_API SCustomListView : public SListView<ItemType>
{
public:
	void UpdateBarStyle(const FScrollBarStyle& inBarStyle)
	{
		WidgetBarStyle = inBarStyle;
		if (ScrollBar.IsValid())
		{
			ScrollBar->SetStyle(&WidgetBarStyle);
		}
	}

private:
	FScrollBarStyle WidgetBarStyle;
};

Hope this helps anyone looking fo a solution

2 Likes

Thanks for solution. Cannot implement scrollbar padding and thicness, because cant override epics code :frowning: They strictly override width of scrollbar…

Sorry for the late reply, I’m not checking enough the forum.

I also needed to override the bar width, so here the snippet I wrote for it.

void UpdateBarStyle(const FScrollBarStyle& inBarStyle)
	{
		WidgetBarStyle = inBarStyle;
		if (STableViewBase::ScrollBar.IsValid())
		{
			STableViewBase::ScrollBar->SetStyle(&WidgetBarStyle);

			FChildren*	barChilds	= STableViewBase::ScrollBar->GetChildren();
			if (barChilds == nullptr && barChilds->Num() == 0)
			{
				UE_LOG(LogTemp, Warning, TEXT("SCustomListView : Can't update background image, ScrollbarWidget Childs are either empty or null"));
				return;
			}
			TSharedRef<SWidget> verticalBox = barChilds->GetChildAt(0);

			FChildren* vBoxChilds = verticalBox->GetChildren();
			if (vBoxChilds == nullptr && vBoxChilds->Num() == 0)
			{
				UE_LOG(LogTemp, Warning, TEXT("SCustomListView : Can't update background image, ScrollbarWidget VerticalBox Childs are either empty or null"));
				return;
			}
			TSharedRef<SWidget> abstractBackgroundBorder = vBoxChilds->GetChildAt(0);
			auto backgroundBorder = StaticCastSharedRef<SBorder>(abstractBackgroundBorder);
			backgroundBorder->SetBorderImage(STableViewBase::ScrollBar->GetOrientation() == EOrientation::Orient_Vertical? 
												&inBarStyle.VerticalBackgroundImage : &inBarStyle.HorizontalBackgroundImage);
		}
	}

	void UpdateBarThickness(const float& inThickness)
	{
		if (STableViewBase::ScrollBar.IsValid())
		{	
			TSharedPtr<SWidget> parentPtr = STableViewBase::ScrollBar->GetParentWidget();
			auto scrollBarBox = StaticCastSharedPtr<SBox>(parentPtr);
			
			scrollBarBox->SetWidthOverride(FOptionalSize(inThickness));
			STableViewBase::ScrollBar->SetThickness(FVector2D(inThickness, 16.0f));
		}
	}

You can refer to “UpdateBarThickness” for overriding Bar width.

Also, I’m reposting the UpdateBarStyle function, because I found out that when we are using SetStyle function, background slate object brush is not updated, so I need find a workaround, by getting the childrens.

Also, to implement that kind of things, I’m using the WidgetReflector to see what each child are doing (and also looking at the code)

Hope this can helps someone