How to manipulate an implicit scrollbar in WPF?

2019-09-12 01:01发布

问题:

How can I access the ScrollViewer which is created automatically by this ListBox? I need to ScrollToBottom;

 <ListBox Name="messageListBox" Height="300"  >
        <ListBox.ItemTemplate >
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding Path=LastUpdateDT, StringFormat=HH:mm}" Margin="0,0,5,0"/>
                    <TextBlock Text="{Binding Path=Message}"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

回答1:

You can recurse down the visual tree and grab the element:

var scroller = GetLogicalChildrenBreadthFirst(messageListBox)
                   .OfType<ScrollViewer>().First();

/// <summary>
/// Helper function that returns a list of the visual children.
/// </summary>
/// <param name="parent">Element whose visual children will be returned.</param>
/// <returns>A collection of visualchildren.</returns>
private IEnumerable<FrameworkElement> GetLogicalChildrenBreadthFirst(FrameworkElement parent)
{
    if (parent == null) throw new ArgumentNullException("parent");

    Queue<FrameworkElement> queue = new Queue<FrameworkElement>(GetVisualChildren(parent).OfType<FrameworkElement>());

    while (queue.Count > 0)
    {
        FrameworkElement element = queue.Dequeue();
        yield return element;

        foreach (FrameworkElement visualChild in GetVisualChildren(element).OfType<FrameworkElement>())
            queue.Enqueue(visualChild);
    }
}

/// <summary>
/// Helper function that returns the direct visual children of an element.
/// </summary>
/// <param name="parent">The element whose visual children will be returned.</param>
/// <returns>A collection of visualchildren.</returns>
private IEnumerable<DependencyObject> GetVisualChildren(DependencyObject parent)
{
    if (parent == null) throw new ArgumentNullException("parent");

    int childCount = VisualTreeHelper.GetChildrenCount(parent);
    for (int counter = 0; counter < childCount; counter++)
    {
        yield return VisualTreeHelper.GetChild(parent, counter);
    }
}


回答2:

Easy way to scroll to the bottom:

listBox1.ScrollIntoView(listBox1.Items[listBox1.Items.Count - 1]);