2011-06-13 149 views
11

我正在编写我的自定义WPF ItemsControl以显示项目列表。该项目显示嵌入的ScrollViewer内:如何将WPF 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; 
     } 
    } 
} 

回答

13

类似下面的什么位置:

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)); 
7

使用UIElement.TranslatePoint()来计算要滚动到

使用ScrollViewer.ScrollToVerticalOffset()做滚动

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

REF:https://msdn.microsoft.com/en-us/library/ms598110.aspx

更新:(感谢@jmbpiano)请注意,它不会将控件精确地带到当前的鼠标光标位置。它只是把控制带到一个可见的位置,操作员可以用鼠标点击它(99%的案例都是发现这个问题的人都可能需要)。

+0

非常感谢!我用其他方式度过了一整天,但最后你的解决方案救了我..真的非常感谢这么多! – 2016-05-27 09:42:39

+2

这实际上并没有实现提问者的要求,因为它完全忽略了鼠标的位置,但它至少将屏幕上的控件显示在屏幕上(在99%的案例中,所有发现此问题的人都可能需要)。所以这当然是一个宝贵的贡献。 – jmbpiano 2016-10-20 21:00:24

+0

这非常符合我的需求,谢谢! – 2017-07-16 11:24:38