Listview - getting started in BP

Amazingly thorough write-up, friend. I know this is years old but I wanted to drop in to show appreciation. I’m trying to use a list view for a server browser and was running into “the pitfall” you noted. I love that you explained what’s going on there. Mad props!

I seem to still be having issues with getting my “updated” EntryWidget displayed in my ListView; it is adding the “default” entry data. I’m using this to make a server list. I’m spawning a ListView and adding it as a child to my WidgetSwitcher using Blueprint (my intent is to load 12 servers to the ListView, then add a new ListView to the WidgetSwitcher and I can flip through them like pages). From there I spawn a ServerEntry (passing it the session result as a constructor parameter) and add it to my ListView, but it looks like the session result is coming in blank when the ServerEntry receives it and I’m not sure why.

Edit: Figured it out! All I had wrong is that at the end (Step 5, where the example sets the text variable) I was executing a function and executing it for the list item object instead of “This” self reference object. It’s working now and I so appreciate this write-up!

Screenshot of my beautiful yet hideous server browser attached. They all show as the same because I’m just looping the same single server result 30+ times for testing.

The Get List Item Object function has been removed so that part is not needed any more.

If you get crashes when adding items to the listview, make sure the same instance is not added twice or more, that will cause a crash. Check your crash log, if it says something like below, then that is the cause.

LogSlate: Warning: WidgetMapToItem length (5) does not match ItemsWithGeneratedWidgets length (4). This is often because the same item is in the list more than once in ListViewT<ItemType>[ListViewBase.h(216)]. Diagnostics follow.
LogSlate: Warning:
LogSlate: Warning: ItemToWidgetMap :
LogSlate: Warning: 0xb1596b00 -> 0xacb0b010 @ ObjectTableRowT[ListViewBase.h(472)]
etc.

With that method, each added item is a different instance. I don’t know what causes your crashes.

Hey, does anyone know how to get the location of a widget in a list view? I tried slotting it and getting its position, but that returned (0,0).

Woah, this is absolutely horrifying. I wanted to create a simple list of items for a menu, but I think I will pass after seeing that I need to read a brutal wall of text just to create a simple list :frowning:

1 Like

Thank you very much for making this post, it was very useful!

Do you know how to completely expand a Tree View with many levels, without having to click all the nodes? I need to completely display a whole Tree on startup. The Tree View class has a Expand All, but its pointless because children are actually added to the Tree View whenever the **On BP on Get Item Children 0 **is called.

I’m a bit rusty since I haven’t used treeview in a long time. But what I found was this:
Getting Children does not actually add those children to the listview items. So if you print the number of children the treeview has, it will always only be the amount that was actually added as items, no matter how many have children are displayed.
So, the Expand All description says, “Expands all items with children”. All ITEMS. So this node only expands the Items, or the base level of the tree.

You can use the Set Item Expansion function to expand an item without clicking on it.
So if you set its expansion during the Listviews Generated/Initialized event, it will expand the items as they are initialized. So now by default all Items will be expanded.

But you need some sort of query to know if they should be expanded when they are generated, other vice they will always become expanded as you scroll through the list.
So I used a Setup Boolean that is true by default and when all the items are added to the listview, it is set to false.

Try this;

You’ll notice that children are not showing up in one frame, but very quickly. Which is unfortunate, because that means we have to use a timer with an estimate on how long it takes the children to all be expanded, before we can set Setup to false.

It’s quite simple, but not that elegant. But it was the only way I could come up with.

Hi, and thank you for the excellent explanation.

I managed to create a simple list with text entries adding to it and a scroll bar appearing on the side, that’s quite nice, BUT I really need to change something.

Right now entries are added from top to bottom and the list does not automatically scroll to the new entries. Which means eventually new entries are invisible unless the user scrolls down, instead of the list automatically focusing on the new items.

Is there a way to make the list focus on new entries? Or to change the order in which new entries are added (from bottom to top instead of top to bottom)?

Thanks!

Hi, I’m not the OP but wanted to drop a quick line. There are a few functions you can look into like “Scroll Widget Into View” or “Scroll To End”. You need to click on your ScrollBox in the designer and check the “Is Variable” option in the Details. Then use that variable in the Graph to access these functions.

Ah, thank you! I suspected there was something very simple to do, but being an Unreal noob, I could not find it. Thanks a lot!

This is a really great write-up, and even though I had 0 knowledge going into this, I think I’ve been able to follow along, though with some difficulty.

My question concerns the TreeView. I’m able to get all actors of class and their children, but I’m also trying to get the children’s children as well.
For example, if I have:
VBox
->Box1
->->Box2
->Box3
Only Box1 and Box3 appear in the tree view, and Box1 doesn’t display that it has any children (unless I Include All Descendents, but the hierarchy remains broken). I was wondering how to implement this, if at all. I assume the way to do so is in the initial Event Construct, but I only found 2 examples with the node networks using it and didn’t know if I was missing anything, such as iterating through children, perhaps the Get Item Children func?

Thanks!

Yes, getting the children can be a bit complex, because it so depends on what the tree is.

It should be easy to ask “Does Box have a Box?”
In the case that Box1,2,3 might be child actor components, Box0 might return the Child Actor Component as the item, which you must then request the Actor reference it is holding, otherwise the next question will be “Does childactorcomponent have child?” - which returns none.

In the case that Box is a widget, that becomes a bit difficult to answer.

But instead of relying on scene hierarchy, you could make an interface that asks the Object (Item) to return Objects (children). Having the Box class implement this interface, you have better control of how and which children are returned. I recommend this method, interfaces are quite easy to use once you read up on them.

I think I get what you’re saying, but might’ve messed up in my explanation (I shouldn’t have used ‘Box’ for all of my examples).

The Box Actor has children Static Mesh components that could be boxes, spheres, you name it, not necessarily Actors on Actors (unless I misunderstand what an Actor is). If I’m trying to get these, would I still implement an interface in my BP_Actor Class? And then it looks like I would plug the interface function into the main Treeview Widget, specifically the On Tree BP Get Item 0.

snip_03.PNG](filedata/fetch?id=1831931&d=1605193638)

Sorry if this is a redundant question, just trying to wrap my head around this.

Okay. So in your BP logic I immediately spot the problem, which is that first you ask if the Item is a BP Actor. If it succeeds, gets child components. And it does succeed the first time, because that’s the Item. But then the same question is asked to each child, in this case scene components; cast as BP Actor -> fails, return empty array. So with that logic a scene component will never return a child.
Instead of returning an empty array if the BP Actor cast fails, instead ask another question. You know it’s not the BP Actor class, so now cast the item as a scene component. If that succeeds, get its children and return them. If it does not have any children, it will return 0.
It’s when all things fail, that you need to return an empty array. And in your case a print string to inform about the error, because that should never happen.

As for using an interface for this, it is possible yes but I don’t really know if I would go with that or not.
What you would have to do with the interface is to have an Object input and an array of object outputs (the children).
Then, you’d have to add a query for each possible object.

  1. Does Object == BP Actor [self]? if true, return these manually selected children.
    if false
  2. Does Object == Box0 [That scene component]? if true, return these manually selected children.
    If false
  3. Does object == Box1 [That scene component]?
    etc…
    It’s not scaleable, and would have to be done in each of the classes that implements the interface.

Ah, that did the trick! Thank you so much!

Is there a reason why ListView lacks the “Scroll” section in the Details pane that a Scroll Box has? They both have scrolling.

I know this is super old, but I ended up going into my ItemObject class and added a variable named Text and checked the instance editable and expose on spawn and it worked. I’m still slowly going through this, but in case others later on run into this problem.

Is there any way to create a some horizontal list views inside one vertical list view with propper touch processeng?
Now I can’t scroll outer list view on mobile - only inner horizontal list views are scrolled by touch inside them. Outer list is scrolling only by scrollbar.

Hello!

Two questions as im a bit lost, being this the first time doing this.

  • As pointed out previously, the function GetItem is not longer available, but I dont have an intuition of how to use what is there now. Can someone point out how to do so.

  • I would like to populate the list with names taken from the Content Browser, in an Utility Widget BP, how we can do that.

Thanks!