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;
}
}
}
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));
// 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).
Use UIElement.TranslatePoint() to calculate what position you want to scroll to
Use ScrollViewer.ScrollToVerticalOffset() to do the scrolling
Try this below code :
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)
{
}
}
来源:https://stackoverflow.com/questions/6336441/how-to-scroll-wpf-scrollviewers-content-to-specific-location