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.
我有一个包含文本块项目堆栈的scrollviewer(实际上,这些可能是tabitems,我在scrollviewer中使用stackpanel来覆盖tabcontrol模板中的默认tabpanel)。我希望能够做的是,当更改选定的选项卡时,将新选择的选项卡移动到滚动查看器可见区域的中心。理想情况下,这适用于所有选项卡,甚至是远端的选项卡,但我愿意能够告诉滚动查看器滚动使得特定元素尽可能接近居中。
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.
在WPF中有没有明显的方法来实现这一目标?我现在能想到的所有解决方案都涉及很多关于自定义控件的工作。
3 个解决方案
#1
7
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)
您正在寻找ScrollViewer.ScrollToHorizontalOffset()。只需要计算所选元素相对于stackpanel的偏移量。您可以使用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
为了使它看起来漂亮,请在计时器中调用ScrollToHorizontalOffset以使滚动“动画”而不是跳转
#2
12
You can easily set the content to the center using the following code;
您可以使用以下代码轻松地将内容设置为中心;
scrollviewer.ScrollToVerticalOffset(scrollviewer.ScrollableHeight / 2);
scrollviewer.ScrollToHorizontalOffset(scrollviewer.ScrollableWidth / 2);
#3
-1
This worked for me:
这对我有用:
//for ScrollViewer s;
s.ScrollToHorizontalOffset((s.ExtentWidth - s.ViewportWidth) / 2);
s.ScrollToVerticalOffset((s.ExtentHeight - s.ViewportHeight) / 2);
#1
7
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)
您正在寻找ScrollViewer.ScrollToHorizontalOffset()。只需要计算所选元素相对于stackpanel的偏移量。您可以使用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
为了使它看起来漂亮,请在计时器中调用ScrollToHorizontalOffset以使滚动“动画”而不是跳转
#2
12
You can easily set the content to the center using the following code;
您可以使用以下代码轻松地将内容设置为中心;
scrollviewer.ScrollToVerticalOffset(scrollviewer.ScrollableHeight / 2);
scrollviewer.ScrollToHorizontalOffset(scrollviewer.ScrollableWidth / 2);
#3
-1
This worked for me:
这对我有用:
//for ScrollViewer s;
s.ScrollToHorizontalOffset((s.ExtentWidth - s.ViewportWidth) / 2);
s.ScrollToVerticalOffset((s.ExtentHeight - s.ViewportHeight) / 2);