How to scroll WPF ScrollViewer's content to specific location

38,931

Solution 1

Something like the following:

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

Solution 2

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

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

UPDATE: (thanks to @jmbpiano) Note, it does not bring the control exactly to the current mouse cursor position. It just brings the control to a visible position, where the Operator will be able to click it with the mouse (which in 99% of cases is all someone who finds this question is likely to need).

Solution 3

Use UIElement.TranslatePoint() to calculate what position you want to scroll to

Use ScrollViewer.ScrollToVerticalOffset() to do the scrolling

Share:
38,931
Metro
Author by

Metro

Updated on July 02, 2020

Comments

  • Metro
    Metro almost 4 years

    I am writing my custom WPF ItemsControl to display a list of item. The items are shown embedded inside a ScrollViewer:

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

    I want to make sure that when I move the mouse into the control, a particular item (marked as selected) will be scrolled into the mouse position. In my OnMouseEnter method I am able to find the item but I don't know what to do next. Does anyone have any idea?

    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;
            }
        }
    }
    
  • Kay Lee
    Kay Lee almost 8 years
    Thank you so much ! I spent a whole day with other ways but finally your solution saved me..really really appreciate so much !!!
  • jmbpiano
    jmbpiano over 7 years
    This doesn't actually do what the asker requested, as it completely ignores the mouse's position, but it does at least bring the control into view on the screen (which in 99% of cases is all someone who finds this question is likely to need). So it's certainly a valuable contribution.
  • Nagendra Velaga
    Nagendra Velaga almost 5 years
    This will help you to scroll the scrollbar with the help of visual tree in wpf/MVVM
  • eran otzap
    eran otzap over 4 years
    where did the 'e' arg come from ?
  • H.B.
    H.B. over 4 years
    @eranotzap: From the MouseEnter event handler (see question: OnMouseEnter(MouseEventArgs e)).
  • Mike97
    Mike97 over 3 years
    Thanks! This really save the day!