en mi humilde opinión, la forma más clara de hacerlo es usando un "comportamiento" a través de un AttachedProperty
. Un AttachedProperty
es un mecanismo para extender la funcionalidad de controles existentes.
En primer lugar, crear una clase para mantener el AtachedProperty
, por ejemplo:
public class ScrollViewerBehavior
{
public static bool GetAutoScrollToTop(DependencyObject obj)
{
return (bool)obj.GetValue(AutoScrollToTopProperty);
}
public static void SetAutoScrollToTop(DependencyObject obj, bool value)
{
obj.SetValue(AutoScrollToTopProperty, value);
}
public static readonly DependencyProperty AutoScrollToTopProperty =
DependencyProperty.RegisterAttached("AutoScrollToTop", typeof(bool), typeof(ScrollViewerBehavior), new PropertyMetadata(false, (o, e) =>
{
var scrollViewer = o as ScrollViewer;
if (scrollViewer == null)
{
return;
}
if ((bool)e.NewValue)
{
scrollViewer.ScrollToTop();
SetAutoScrollToTop(o, false);
}
}));
}
Esta propiedad adjunta permite una ScrollViewer
tener "mágicamente" una nueva propiedad de tipo Boolean
, actuando como un DependencyProperty
en su XAML. Si enlaza esta propiedad a una propiedad estándar en su modelo de vista, por ejemplo:
private bool _reset;
public bool Reset
{
get { return _reset; }
set
{
_reset = value;
if(PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Reset"));
}
}
(de nuevo, el nombre depende de usted) y luego se establece este Reset
propiedad a true
, su ScrollViewer
se desplazará hacia arriba. He llamado AtachedProperty
como AutoScrollToTop, pero el nombre no es importante para este propósito.
El XAML será algo como:
<ScrollViewer my:ScrollViewerBehavior.AutoScrollToTop="{Binding Reset, Mode=TwoWay}">
<ListView>
<ListView.View>
<GridView>
<GridViewColumn
Header = "Name"
DisplayMemberBinding="{Binding Path=Name}"
/>
</GridView>
</ListView.View>
</ListView>
</ScrollViewer>
Nota: my
es el espacio de nombres donde sus vidas ScrollViewerBehavior
clase. Por ejemplo: xmlns:my="clr-namespace:MyApp.Behaviors"
Finalmente, lo único que tiene que hacer en su ViewModel es establecer Reset = true
cuando lo desee, en su caso, cuando agrega o elimina un elemento de la colección.
Soy nuevo en MVVM: en su primera opción sería genial si pudiera mostrar algún código sobre cómo implementar el evento + suscribirse. ¿Es como [esto] (http://stackoverflow.com/a/10109366/345659)? Leí en algún lugar un patrón de evento débil (lo que sea que sea) es preferible para evitar pérdidas de memoria. – JumpingJezza
He agregado un ejemplo de código con el enfoque de MVVM más fácil para su problema, pero puede refinarse mucho más, por supuesto. Si desea evitar el uso de código subyacente, busque DataEventTriggers. Si no te importa el código subyacente pero te preocupan las pérdidas de memoria, busca eventos débiles. – almulo
Y, por último, dado que la lógica que desea es 100% relacionada con la vista (tiene el desplazamiento ListView cada vez que se agrega o elimina un elemento), también puede implementarlo como una propiedad Comportamiento/adjunta, o extender ListView. Eso podría ser un poco más intrincado, pero te animo a pensar en esas opciones. – almulo