Delay's Blog is the blog of David Anson, a Microsoft developer who works with C#, XAML, HTML, and Azure.
This blog has moved to a new location and comments have been disabled.
All old posts, new posts, and future comments can be found on The blog of dlaa.me.
See you there!
I recently found myself wanting a method I could call to bring one of the items in a WPF ListBox into view. In my scenario, the user would recognize the item when he/she saw it, so my problem wasn't about setting focus or rendering a highlight; it was just about bringing the item into view so it could be seen and manipulated. I started in the obvious place: the ListBox.ScrollIntoView method. Sure enough, a call to this method scrolled the item into view just like it was supposed to - and yet I wasn't completely satisfied... :)
You see, I didn't just want the item to be visible, I wanted it to be centered as well. I can't imagine I'm the first person to want to do this, but a quick web search didn't turn up anything relevant. I figured it'd be easy enough to write some code to implement the behavior myself, so I turned the problem over a bit in my head and was all giddy when I caught a gotcha prior to coding. :) Then, having decided on the implementation, I went ahead and typed up my ScrollIntoViewCentered extension method and gave it a try...
Darn... While my code worked as well as ScrollIntoView, it also wasn't any better. Specifically, the item wasn't centered like I wanted... :( A little poking around and some targeted experimentation turned up a second gotcha I'd missed. Once I'd addressed the second issue, the code worked fine and I continued with what I was originally doing.
[Click here to download the code for the ListBoxExtensionsDemo sample application.]
You can find the complete code for ScrollIntoViewCentered below; here's a quick discussion of the two gotchas:
The ScrollIntoViewCentered method is hardly rocket science - but it is pretty handy. :) Thanks to the magic of extension methods, it looks just like the ListBox API it was inspired by and ends up being both easy to discover and easy to use.
I hope you like it!
/// Class implementing helpful extensions to ListBox.
public static class ListBoxExtensions
/// Causes the object to scroll into view centered.
/// <param name="listBox">ListBox instance.</param>
/// <param name="item">Object to scroll.</param>
Justification = "Deliberately targeting ListBox.")]
public static void ScrollIntoViewCentered(this ListBox listBox, object item)
"VirtualizingStackPanel.IsVirtualizing must be disabled for ScrollIntoViewCentered to work.");
"ScrollViewer.GetCanContentScroll must be disabled for ScrollIntoViewCentered to work.");
// Get the container for the specified item
var container = listBox.ItemContainerGenerator.ContainerFromItem(item) as FrameworkElement;
if (null != container)
// Get the bounds of the item container
var rect = new Rect(new Point(), container.RenderSize);
// Find constraining parent (either the nearest ScrollContentPresenter or the ListBox itself)
FrameworkElement constrainingParent = container;
constrainingParent = VisualTreeHelper.GetParent(constrainingParent) as FrameworkElement;
} while ((null != constrainingParent) &&
(listBox != constrainingParent) &&
!(constrainingParent is ScrollContentPresenter));
if (null != constrainingParent)
// Inflate rect to fill the constraining parent
Math.Max((constrainingParent.ActualWidth - rect.Width) / 2, 0),
Math.Max((constrainingParent.ActualHeight - rect.Height) / 2, 0));
// Bring the (inflated) bounds into view