Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

444
Vistas
La animación de Xamarin.Forms dentro de Listview deja de funcionar si la colección cambia

Tengo dificultades para entender qué está pasando con mi animación.

Viewmodel se compone de una ObservableCollection y cada elemento contiene una ObservableCollection secundaria.

La colección principal está vinculada a un BindableLayout Parents El ItemTemplate de ese diseño contiene una vista de lista para mostrar los elementos del niño.

 <StackLayout BindableLayout.ItemsSource ="{Binding Parents}"> <BindableLayout.ItemTemplate> <DataTemplate x:DataType="models:ParentRows"> <StackLayout> <Grid BackgroundColor="White" > <!-- Some bindable content there --> </Grid> <ListView ItemsSource="{Binding Childs}" CachingStrategy="RecycleElementAndDataTemplate" RowHeight="50"> <ListView.ItemTemplate> <DataTemplate x:DataType="models:ChildRows"> <ViewCell> <StackLayout BackgroundColor="White"> <controls:AnimatedGrid Refresh="{Binding Animation}" <!-- Some bindable content there --> </controls:AnimatedGrid> </StackLayout> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView> </StackLayout> </DataTemplate> </BindableLayout.ItemTemplate> </StackLayout>

Estoy usando un AnimatedGrid en la vista de lista secundaria, este control se hereda de Grid. Tiene una BindableProperty adicional llamada Refresh y un código de animación que se llama cada vez que cambia la propiedad Refresh .

 private async void AnimateItem() { await Device.InvokeOnMainThreadAsync(() => { this.RotateTo(360,500); }); }

Todo funciona bien hasta que empiezo a filtrar la lista. Una vez que filtre la lista, la llamada posterior de AnimateItem no tendrá efecto . Para ser más precisos, si el elemento principal se eliminó de la lista y luego se volvió a agregar, los elementos secundarios de este elemento principal nunca volverán a animarse. Filtrar la lista consiste en quitar/insertar padres en la colección observable (myCollection.Remove(item), myCollection.Insert(index, item), usando los métodos de colección del marco) .

Esto no parece ser un problema de enlace de colección observable, ya que los valores dentro de la colección principal y secundaria aún se actualizan perfectamente. Cambiar CachingStrategy tampoco tiene impacto en el problema.

Descubrí que, si reemplazo el control ListView por un CollectionView, el problema desaparece . Sin embargo, realmente quiero encontrar una solución que me permita mantener el control de vista de lista, ya que cambiar a CollectionView generaría muchos otros efectos no deseados.

Editar 22/02/2022: Hice un proyecto de muestra para reproducir el problema en github.

  • Básicamente, puede hacer clic en "Rotar al azar" varias veces para hacer que el niño gire al azar.
  • Una vez que haga clic en "Eliminar y agregar 2 padres", puede ver que los elementos eliminados/reinsertados ya no rotan.

Editar 15/03/2022: Todavía no puedo entender qué está mal. Sin embargo, para fines de prueba, agregué en el constructor de control, una tarea.retraso seguido de una llamada de animación, y esta llamada funciona en elementos filtrados. Eso está más allá de mi comprensión.

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

La solución

En su clase AnimatedGrid , agregue un indicador isAttached y agregue las siguientes líneas a su anulación OnPropertyChanged :

 bool isAttached = false; protected override void OnPropertyChanged([CallerMemberName] string propertyName = null) { base.OnPropertyChanged(propertyName); if (propertyName == "Renderer") { isAttached = !isAttached; if (!isAttached) this.RemoveBinding(RefreshProperty); } if (propertyName == nameof(Refresh)) { ...

El porque

Descargo de responsabilidad: me llevó mucho tiempo darme cuenta de lo que estaba pasando aquí, y aunque pude solucionar el problema, no diría que lo entiendo completa y perfectamente. Creo que esto es un error en Xamarin, y en su caso, presentaría un problema en Github (aunque tal vez MAUI lo corrija ...)

Cuando se elimina un ChildItem ( do Filter ), la propiedad Refresh del antiguo ChildItem-AnimatedGrid permanece vinculada a la propiedad AnimationInt del ChildItem .

Cuando se agrega nuevamente un ChildItem ( eliminar filtro ), se crea una nueva vista.

Ahora el problema es evidente: cuando la propiedad AnimationInt de ChildItem cambia (toque el botón ROTATE RANDOM ) se notifica la Refresh de ChildItem-AnimatedGrid anterior , y luego se gira la Vista anterior, pero la nueva permanece sin cambios (no gira ).


Una vez que se comprende el problema, debemos descubrir cómo eliminar el enlace de la vista anterior cuando la vista está separada : bueno, para hacer esto usé el hecho de que la propiedad Renderer de VisualElement está configurada/modificada cuando el elemento es adjunto y nuevamente cuando se separa: la primera vez que se llama configuro el indicador isAttached en true . La segunda vez que se llama, establezco el indicador en false y elimino el enlace. Eliminar el enlace de la vista anterior permite que la nueva vista se enlace correctamente.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda