【问题标题】:How to scroll WPF ScrollViewer's content to specific location如何将 WPF ScrollViewer 的内容滚动到特定位置
【发布时间】:2019-07-02 17:23:24
【问题描述】:

我正在编写我的自定义 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;
        }
    }
}

【问题讨论】:

    标签: wpf mouse position scrollviewer


    【解决方案1】:
    // How to scroll the uiElement to the mouse position?
    uiElement.BringIntoView();
    

    参考号:https://msdn.microsoft.com/en-us/library/ms598110.aspx

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

    【讨论】:

    • 非常感谢!我花了一整天的时间用其他方法,但最后你的解决方案救了我..真的非常感谢!!!
    • 这实际上并没有按照提问者的要求做,因为它完全忽略了鼠标的位置,但它至少可以在屏幕上看到控件(在 99% 的情况下都是某人谁发现这个问题很可能需要)。因此,这无疑是一项宝贵的贡献。
    • 谢谢!这真的节省了一天!
    【解决方案2】:

    类似于以下内容:

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

    【讨论】:

    • 'e' arg 是从哪里来的?
    • @eranotzap:来自MouseEnter 事件处理程序(请参阅问题:OnMouseEnter(MouseEventArgs e))。
    【解决方案3】:

    使用 UIElement.TranslatePoint() 计算您想要滚动到的位置

    使用 ScrollViewer.ScrollToVerticalOffset() 进行滚动

    【讨论】:

      【解决方案4】:

      试试下面的代码:

      
      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 中的可视化树的帮助下滚动滚动条
      猜你喜欢
      • 2012-12-07
      • 1970-01-01
      • 2012-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多