如何将WPF ScrollViewer的内容滚动到特定位置

23

我正在编写自定义的WPF ItemsControl以显示一个项目列表。这些项目嵌入在ScrollViewer中显示:

<Style TargetType="MyCustomItemsControl">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="MyCustomItemsControl">
                    <ScrollViewer x:Name="PART_MyScrollViewer" >
                           <ItemsPresenter/>
                    </ScrollViewer>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
</Style>

我希望当鼠标移入控件时,特定的项(标记为选定)将滚动到鼠标位置。在我的OnMouseEnter方法中,我能够找到该项,但不知道下一步该怎么做。有人有什么想法吗?

protected override void OnMouseEnter(MouseEventArgs e)
{
    for (int i = 0; i < Items.Count; i++)
    {
        ContentPresenter uiElement = (ContentPresenter)ItemContainerGenerator.ContainerFromIndex(i);
        var item = uiElement.Content as MyCustomObject;
        if (item.IsSelected)
        {
            // How to scroll the uiElement to the mouse position?
            break;
        }
    }
}
4个回答

38
// How to scroll the uiElement to the mouse position?
uiElement.BringIntoView();

参考资料:https://msdn.microsoft.com/zh-cn/library/ms598110.aspx

更新:(感谢 @jmbpiano)注意,此方法并不会将控件精确地带到当前鼠标光标位置。它只会将控件带到一个可见位置,在那里操作者可以使用鼠标单击它(这在99%的情况下是所有发现这个问题的人所需要的)。


1
非常感谢!我用其他方法整整花了一天的时间,但最终你的解决方案拯救了我...真的非常感激!!! - Kay Lee
5
这实际上并没有达到提问者的要求,因为它完全忽略了鼠标的位置,但至少它能在屏幕上将控件带入视野中(对于99%的人来说,这可能就是发现这个问题时所需的所有内容)。因此,它肯定是一项有价值的贡献。 - jmbpiano
1
谢谢!这真的救了一天! - Mike97

26

类似以下内容:

var sv = (ScrollViewer)Template.FindName("PART_MyScrollViewer", this); // If you do not already have a reference to it somewhere.
var ip = (ItemsPresenter)sv.Content;
var point = item.TranslatePoint(new Point() - (Vector)e.GetPosition(sv), ip);
sv.ScrollToVerticalOffset(point.Y + (item.ActualHeight / 2));

1
“e”参数从哪里来的? - eran otzap
MouseEnter事件处理程序(参见问题:OnMouseEnter(MouseEventArgs e))。 - H.B.

9
使用UIElement.TranslatePoint()计算您想要滚动到的位置。 使用ScrollViewer.ScrollToVerticalOffset()进行滚动。

0
尝试下面的代码:

private void ScrollViewerFromVSTree(DependencyObject element, double pos)
{
    try
    {
        int totalElementcount = VisualTreeHelper.GetChildrenCount(element);
        for (int counter = 0; counter < totalElementcount; counter++)
        {
            DependencyObject ele = VisualTreeHelper.GetChild(element, counter);
            if (ele.GetType().Name == "ScrollViewer")
            {
                ScrollViewer scrollViewer = ele as ScrollViewer;
                if (pos > "YourAssumption") // for me it is 610
                {
                    scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset + 45);
                }
                else if (pos < "YourAssumption") //for me it is 40
                {
                    scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset - 45);
                }
                break;
            }
            ScrollViewerFromVSTree(VisualTreeHelper.GetChild(element, counter), pos);
        }
    }
    catch (Exception)
    {
    }
}


这将帮助您通过WPF / MVVM中的可视树滚动滚动条。 - Nagendra Velaga

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接