Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Resolved ScrollView: How Do I Consistently Find the Index of A Child Element?

Discussion in 'UI Toolkit' started by ShokWayve, Sep 14, 2023.

  1. ShokWayve

    ShokWayve

    Joined:
    Jan 16, 2013
    Posts:
    117
    Greetings,

    How can I reliably get the index of an item in a scrollview, and enable the scrollview to recognize it's own children?

    Even when an element gains focus, and that very element is accessed in code (via a FocusInEvent), when that element is given back to the ScrollView to find, it can't find it. This is hard for me to understand since the element is definitely in the scrollview and is where it came from in the first place.

    Any ideas?

    Thanks.
     
  2. Hellfim

    Hellfim

    Joined:
    Sep 11, 2014
    Posts:
    91
    Are you sure your element is a DIRECT child of a ScrollView and not a child of another ScrollView's child?
    I mean if you have structure like:
    Code (csharp):
    1.  
    2. scroll-view
    3. |--content-container
    4.    |--child-1
    5.    |--child-2
    6.       |--focused-element
    7.  
    ScrollView.ScrollTo will not work
     
  3. ShokWayve

    ShokWayve

    Joined:
    Jan 16, 2013
    Posts:
    117
    Thanks for your response. I will check. However, I thought that the elements in the scrollview are a direct child of the scrollview.

    Also, when I use ScrollTo the first time, it seems to work.

    I will check the content container and follow up.
     
  4. ShokWayve

    ShokWayve

    Joined:
    Jan 16, 2013
    Posts:
    117
    I just checked. Even when I tried using the content container, for some reason it cannot seem to find the element which is for sure in the scrollview.

    If you think of anything else, let me know.

    Thanks for your reply.
     
  5. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
    The actual elements you add to a scroll view are nested down into a few different visual elements that it uses for vertical/horizontal scrolling. They're not direct children.

    Use the UI debugger to see what's really going on: https://docs.unity3d.com/Manual/UIE-ui-debugger.html
     
  6. ShokWayve

    ShokWayve

    Joined:
    Jan 16, 2013
    Posts:
    117
    2023-09-19T11_12_38.png

    Thanks for suggesting the UI debugger. I located where the items I added are located. However, when I try to get the index of them - e.g., myContentContainer.IndexOf(theHouseCard) - it still can't find them. Recall, I get the actual item when it is selected by responding to the selection event. So, the item is in there.

    Note: I get the content container by doing a Q search by name. The content container is located and present in the code.

    I will keep trying different things. If you think of anything let me know.

    Thanks again.
     
  7. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
    Care to share your code?

    That said, the
    contentContainer
    property for the ScrollView visual element should return the same visual element you're querying.

    That said x2, your visual elements should not be your data structure. You should be tracking these independently via some other means, with the UI just a visual representation of the underlying data.
     
    ShokWayve likes this.
  8. ShokWayve

    ShokWayve

    Joined:
    Jan 16, 2013
    Posts:
    117
    Thanks to everyone @spiney199 and @Hellfim for your answers. I solved it. I hope the information below is helpful to someone.

    The first issue was that I was using the FocusInEvent.Target. Once I used FocusInEvent.currentTarget, I was able to locate the Visual Element either in my own List of Visual Elements in the scrollview, or just by accessing the contentContainer of the ScrollView and submitting the Visual Element.

    The code example is:

    VisualElement focusElement = houseCards.contentContainer.Children().First(x => x == theElement);
    focusElement.Q<VisualElement>("container").Focus();

    houseCards is the ScrollView. As I stated, it seems that FocusInEvent.currentTarget gets the actual visual element that has received focus.
     
    Hellfim likes this.