Как прокрутить содержимое WPF ScrollViewer в определенное место
Я пишу свой пользовательский 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;
}
}
}
3 ответа
Что-то вроде следующего:
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
ОБНОВЛЕНИЕ: (благодаря @jmbpiano) Обратите внимание, что оно не приводит элемент управления точно к текущей позиции курсора мыши. Он просто переводит элемент управления в видимое положение, где Оператор сможет щелкнуть по нему мышью (что в 99% случаев является тем, кто может найти этот вопрос, скорее всего).
Используйте UIElement.TranslatePoint(), чтобы вычислить, на какую позицию вы хотите перейти
Используйте ScrollViewer.ScrollToVerticalOffset() для прокрутки
Попробуйте следующий код:
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)
{
}
}