16
votes

I have a scrollviewer that contains a stackpanel of textblock items (actually, these are probably tabitems, I'm using a stackpanel inside a scrollviewer to override the default tabpanel in a tabcontrol template). What I'd like to be able to do is, when the selected tab is changed, move the newly selected tab to the center of the scrollviewer's visible area. Ideally this would work for all the tabs, even those on the far sides, but I would settle for being able to tell the scrollviewer to scroll such that a particular element is as close to centered as possible.

Are there any obvious ways to achieve this in WPF? All the solutions I can think of right now involve a lot of work on custom controls.

enter image description here

3
@Robert Levy: That is not how it should be done, if no answer actually answers a question there is no need to accept any of them.H.B.

3 Answers

16
votes

You can easily set the content to the center using the following code;

scrollviewer.ScrollToVerticalOffset(scrollviewer.ScrollableHeight / 2);
scrollviewer.ScrollToHorizontalOffset(scrollviewer.ScrollableWidth / 2);
7
votes

ScrollViewer.ScrollToHorizontalOffset() is what you are looking for. Just need to calculate what the offset of your selected element is relative to the stackpanel. You can get that with something like selectedElement.TranslatePoint( new Point(), stackPanel)

To make this work for elements at the far ends, you'll need to add some 'blank' elements to the start and end of your scrollviewer to take up the appropriate amount of space.

To make this look pretty, call ScrollToHorizontalOffset in a timer to make the scrolling 'animate' instead of jump

1
votes

This worked for me:

//for ScrollViewer s;
s.ScrollToHorizontalOffset((s.ExtentWidth - s.ViewportWidth) / 2);
s.ScrollToVerticalOffset((s.ExtentHeight - s.ViewportHeight) / 2);