Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to scroll WPF ScrollViewer's content to specific location

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;
        }
    }
}
like image 489
Metro Avatar asked Jun 13 '11 21:06

Metro


3 Answers

// 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).

like image 98
epox Avatar answered Sep 18 '22 21:09

epox


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)); 
like image 28
H.B. Avatar answered Sep 19 '22 21:09

H.B.


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

Use ScrollViewer.ScrollToVerticalOffset() to do the scrolling

like image 24
Robert Levy Avatar answered Sep 17 '22 21:09

Robert Levy