SevenDays
SevenDays

Reputation: 3768

Scroll to bottom of listbox wp7

I have many items(0-100) end need to scroll to the bottom of Listbox which contains it.I tried:

ScrollViewer.SetVerticalScrollBarVisibility(listmy, ScrollBarVisibility.Auto);
            listmy.SelectedItem =  listmy.Items.Count-1;
            listmy.ScrollIntoView(listmy.SelectedItem);
            ScrollViewer.SetVerticalScrollBarVisibility(listmy, ScrollBarVisibility.Disabled);

but this doesn't workds for me.The scrollviewer wraps the listbox and textbox.(listbox vertical scroll in disabled state). UPD xaml:

<Grid>

    <ScrollViewer Name="_ScrollViewer" VerticalScrollBarVisibility="Auto">
        <StackPanel Name="stackPanel" Height="auto">
          <ListBox ScrollViewer.VerticalScrollBarVisibility="Disabled"  x:Name="listmy">
            <ListBox.ItemTemplate>
              <DataTemplate>...

and cs:

listmy.ItemsSource = ((App)Application.Current).DIALOG;
        ScrollViewer.SetVerticalScrollBarVisibility(listmy, ScrollBarVisibility.Auto);
        listmy.SelectedIndex =  listmy.Items.Count-1;
        listmy.ScrollIntoView(listmy.SelectedItem);
        ScrollViewer.SetVerticalScrollBarVisibility(listmy, ScrollBarVisibility.Disabled);

Upvotes: 2

Views: 6401

Answers (4)

Matten
Matten

Reputation: 17621

Came across this one and haven't found the "works out of the box no code-behind" solution, so I just came up with this class:

using System.Windows.Controls;

/// <summary>
/// A list box which automatically scrolls to the last line if new items were added.
/// </summary>
public class AutoscrollListBox : ListBox
{
    /// <summary>
    /// The on items changed.
    /// </summary>
    /// <param name="e">
    /// The e.
    /// </param>
    protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        this.ScrollDown();
        base.OnItemsChanged(e);
    }

    /// <summary>
    /// Scrolls to the last element.
    /// </summary>
    private void ScrollDown()
    {
        if (this.Items.Count > 0)
        {
            var lastItem = this.Items[this.Items.Count - 1];
            this.ScrollIntoView(lastItem);
        }
    }
}

Just use this listbox and no additional "magic" is required.

Upvotes: 2

iCollect.it Ltd
iCollect.it Ltd

Reputation: 93551

I gather you actually want to just ensure the ScrollBar of the ListBox is always fully scrolled to the bottom. The other solutions are only about making sure the last line is visible (not the same thing).

To get the effect you want you can create a simple subclassed ListBox like this:

    using System.Windows.Controls;
    namespace ScrollBarTest
    {
        public class CustomListBox : ListBox
        {
            public void ScrollToBottom()
            {
                var scrollviewer = GetTemplateChild("ScrollViewer") as ScrollViewer;
                scrollviewer.ScrollToVerticalOffset(scrollviewer.ScrollableHeight);
            }
        }
    }

Do not use an outer ScrollViewer as you are in the example, just the subclassed ListBox

Just call the ScrollToBottom() method whenever you want it scrolled to the last line.

The reason for the subclassing is that GetTemplateChild is protected so not accessible from outside of a derived class.

Upvotes: 5

Chris Koenig
Chris Koenig

Reputation: 2748

How about this:

var lastItem = listmy.Items[listmy.Items.Count - 1];
listmy.ScrollIntoView(lastItem);

I tried it on a sample project and it worked great!

Upvotes: 3

hetelek
hetelek

Reputation: 3886

If you simply just set the select index of the ListBox, it should work. I tried it, and it seemed to work fine.

listBox1.SelectedIndex = listBox1.Items.Count - 1;

I've tried that, and it scrolled to the bottom of the ListBox, with no problems.

Upvotes: 1

Related Questions