WPF: Animate ListBox.ScrollViewer.HorizontalOffset?
animation (2)
Tengo una colección de Visual
s en un ListBox
. Necesito encontrar la XPosition
de un elemento dentro de ella y luego animar el HorizontalOffset
del ScrollViewer
ListBox
. Básicamente, quiero crear un método animado ScrollIntoView
.
Esto me da un par de problemas. En primer lugar, ¿cómo puedo obtener una referencia al scrollviewer de ListBox
? En segundo lugar, ¿cómo puedo obtener la XPosition
relativa u HozintalOfffset
de un elemento arbitrario en el ListBox
?
No estoy respondiendo a ninguna entrada en el ListBox
sí, así que no puedo usar las propiedades relacionadas con el Mouse
.
No estoy seguro de si mi método es una buena práctica, pero por el tiempo limitado que tuve, pareció funcionar bien. En vez de usar un storyboard, acabo de utilizar un DispatcherTimer.
ScrollLeftButtonCommand = new DelegateCommand(
o =>
{
var scrollViewer = (ScrollViewer)o;
scrollTimer = new DispatcherTimer();
scrollTimer.Start();
scrollTimer.Interval = TimeSpan.FromMilliseconds(30);
scrollTimer.Tick += (s, e) =>
{
scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset - 50);
if (scrollViewer.HorizontalOffset <= 0)
{
scrollTimer.Stop();
}
};
});
Asegúrate de que sea un temporizador de despacho para que el hilo pueda tomar el control del elemento de la interfaz de usuario
¡También recuerda unir tu objeto en tu vista!
<Button CommandParameter="{Binding ElementName=MyScrollViewer }"
Command="{Binding ScrollLeftButtonCommand }"/>
No creo que puedas usar un guión gráfico de WPF para la animación porque los guiones gráficos animan las propiedades de dependencia de WPF. Deberá llamar a ScrollViewer.ScrollToHorizontalOffset(double)
para desplazarse.
Podría intentar crear una propiedad de dependencia personalizada que llame a SetHorizontalOffset en la función OnDependencyPropertyChanged (). Entonces podrías animar esta propiedad.
public static readonly DependencyProperty ScrollOffsetProperty =
DependencyProperty.Register("ScrollOffset", typeof(double), typeof(YOUR_TYPE),
new FrameworkPropertyMetadata(0.0, new PropertyChangedCallback(OnScrollOffsetChanged)));
public double ScrollOffset
{
get { return (double)GetValue(ScrollOffsetProperty); }
set { SetValue(ScrollOffsetProperty, value); }
}
private static void OnScrollOffsetChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
YOUR_TYPE myObj = obj as YOUR_TYPE;
if (myObj != null)
myObj.SCROLL_VIEWER.ScrollToHorizontalOffset(myObj.ScrollOffset);
}
Para obtener el visor de desplazamiento puede usar VisualTreeHelper para buscar los elementos secundarios visuales de ListBox. Guarde una referencia al ScrollViewer porque lo necesitará más adelante. Prueba esto:
public static childItem FindVisualChild<childItem>(DependencyObject obj)
where childItem : DependencyObject
{
// Iterate through all immediate children
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child != null && child is childItem)
return (childItem)child;
else
{
childItem childOfChild = FindVisualChild<childItem>(child);
if (childOfChild != null)
return childOfChild;
}
}
return null;
}
Esta función devuelve el primer elemento secundario visual del tipo de parámetro. Llame a FindVisualChild<ScrollViewer>(ListBox)
para obtener ScrollViewer.
Finalmente, intente usar UIElement.TranslatePoint(Point, UIElement)
para obtener la posición X del artículo. Llame a esta función en el artículo, pase 0,0 para el punto y pase el ScrollViewer.
Espero que esto ayude.