Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

445
Views
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 answers
Answer question

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!