Topic Author
Posts: 29
Joined: 26 Nov 2013, 04:47

ListBox.ScrollIntoView does not appear to be working directly after a CollectionChanged event

23 Mar 2018, 15:40

When attempting to scroll an item into view with ListBox.ScrollIntoView() after a CollectionChanged event is raised by an ObservableCollection, the method ScrollIntoView throws an exception: NoesisException: Null item added to collection.

Here's the code:
    public class ChatScreen : UserControl, INotifyPropertyChanged
        public ObservableCollection<ChatMessageModel> Messages { get; } = new ObservableCollection<ChatMessageModel>();
        public TextBox SendText { get; private set; }
        public ListBox ListBox { get; private set; }
        public string Message { get; set; }
        public event PropertyChangedEventHandler PropertyChanged;

        public ChatScreen()
            Initialized += onInitialized;
            GUI.LoadComponent( this, "Assets/Ui/Chat/ChatScreen.xaml" );

        private void onInitialized( object sender, EventArgs eventArgs )
            DataContext = this;
            SendText = (TextBox) FindName( "SendText" );
            ListBox = (ListBox) FindName( "ListBox" );
            SendText.TextInput += onMessageSend;
            Messages.CollectionChanged += onNewMessage;

        private void onNewMessage( object sender, NotifyCollectionChangedEventArgs e )
            var item = e.NewItems[0]; //# Confirmed not null through debugging
            ListBox.ScrollIntoView( item );

        private void onMessageSend( object sender, TextCompositionEventArgs textCompositionEventArgs )
            if ( Message != null && Message.Trim().Length > 0 )
                Messages.Add( new ChatMessageModel( "XaeroDegreaz", $"{Message}" ) );
                SendText.Text = null;

        protected virtual void OnPropertyChanged( [CallerMemberName] string propertyName = null )
            PropertyChanged?.Invoke( this, new PropertyChangedEventArgs( propertyName ) );

    public class ChatMessageModel
        public string Username { get; }
        public string Message { get; }
        public string FormattedMessage => $"{Username}: {Message}";

        public ChatMessageModel( string username, string message )
            Username = username.Trim();
            Message = message.Trim();
I believe it has something to do with the item not yet being rendered in the list during that frame, so something internal to the ListBox isn't aware of a child to scroll to. I was able to mitigate this by adding a helper MonoBehaviour with a coroutine that waits until the end of the frame before calling ScrollIntoView on the ListBox:
    public class ChatHelper : MonoBehaviour
        private static ChatHelper instance { get; set; }

        private void Awake()
            instance = this;

        public static void ScrollIntoView( ListBox listBox, object item )
            instance.StartCoroutine( instance.doWork( listBox, item ) );

        private IEnumerator doWork( ListBox listBox, object item )
            yield return new WaitForEndOfFrame();
            listBox.ScrollIntoView( item );
I just thought I'd bring this up, since it seems like it doesn't exactly function the way it does in standard WPF applications. Is there a better way to handle scrolling to newly added items with Noesis? Perhaps I'm missing something really obvious. Thanks!
User avatar
Site Admin
Posts: 3064
Joined: 22 Dec 2011, 19:20

Re: ListBox.ScrollIntoView does not appear to be working directly after a CollectionChanged event

27 Mar 2018, 17:16

Could you please report this problem to our bugtracker?
We will review WPF behavior and implement it the same way.

Who is online

Users browsing this forum: Bing [Bot] and 0 guests