xamarin.android - Xamarin.Forms ListView with uneven row hight not updating layout if items change size after an item has been deleted -


i developing app uses list view show list of appointments. selected appointment , meet conditions should expanded , show information , others should show summarised version. have implemented using listview it's itemtemplate set datatemplate containing stacklayout contains various elements. of these elements have isvisible property bound bool property on view model updated depending on whether item should expanded. listview has it's hashunevenrows set true , rowheight set -1.

when item deleted items collection correctly removed after point other item below on screen (except last item seem work) not change in size though "expand" property being changed , items appear overlayed on other elements there. if items scrolled off screen start working again.

i have developed small test app shows same behaviour simpler , performs actions in response gui interaction remove possibility of being multi threading issues. simple app has button remove top item , list view containing numbered items if not selected number , if selected show "expanded" above number. after items have been deleted size of rows no longer update , stays @ height had when item deleted. causing selected row have white space above number , new rows either show "expanded" or show overlayed on number.

full source code available @ https://github.com/staircase27/xamarinformsandroidlistviewerror/tree/master

the main pages .xaml file contains

<contentpage xmlns="http://xamarin.com/schemas/2014/forms"              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"              x:class="listviewerror.mainpage"              x:name="page"              bindingcontext="{x:reference page}">     <stacklayout orientation="vertical">         <button clicked="menuitem_onclicked" text="remove first item" />         <listview itemssource="{binding items}" itemselected="listview_onitemselected" hasunevenrows="true" rowheight="-1">             <listview.itemtemplate>                 <datatemplate>                     <viewcell>                         <stacklayout orientation="vertical">                             <label isvisible="{binding expand}" text="expanded" verticaltextalignment="center"                                    horizontaltextalignment="center" />                             <label text="{binding id}" verticaltextalignment="center" horizontaltextalignment="center" />                         </stacklayout>                     </viewcell>                 </datatemplate>             </listview.itemtemplate>         </listview>     </stacklayout> </contentpage> 

and relevant parts of code behind file are

public partial class mainpage {     public mainpage()     {         _items = new observablecollection<item>(enumerable.range(0, 10).select(i => new item(i)));         initializecomponent();     }       public ienumerable<item> items => _items;       public sealed class item : inotifypropertychanged     {         public item(int id)         {             id = id;             expand = false;         }           public int id { get; }          public bool expand         {             { return _expand; }             set             {                 if (value == _expand) return;                 _expand = value;                 onpropertychanged();             }         }          public event propertychangedeventhandler propertychanged;           [notifypropertychangedinvocator]         private void onpropertychanged([callermembername] string propertyname = null)         {             propertychanged?.invoke(this, new propertychangedeventargs(propertyname));         }           private bool _expand;     }       private void listview_onitemselected(object sender, selecteditemchangedeventargs e)     {         if (_selecteditem != null)             _selecteditem.expand = false;         _selecteditem = e.selecteditem item;         if (_selecteditem != null)             _selecteditem.expand = true;     }       private void menuitem_onclicked(object sender, eventargs e) => _items.removeat(0);      private item _selecteditem;     private readonly observablecollection<item> _items; } 

this code has been tested using xamarin 4.4.0.34 , xamarin.forms nuget package 2.3.4.224 same behaviour seen older versions too. both developed using visual studio 2015.

in demo app have tried workaround think of reset itemssource on listview fix issue loses current selection. have worked around issues resetting the selecteditem cause selected item picked again. neither of these option main app though changes collection come multiple places , collection provided external component watching changes not easy. list in main app relatively large , there many components in gui per item reloaded entire list change collection expensive , make app hard use. workaround included in respository linked above , requires changing menuitem_onclicked function to

        _items.removeat(0);         item selecteditem = _selecteditem;         listview.selecteditem = null;         listview.itemssource = null;         listview.itemssource = items;         listview.selecteditem = selecteditem; 

screenshots

app working: app working app broken (see entries 7 (not expanded) , 8 (expanded when shouldn't be)): app broken (see entries 7 (not expanded) , 8 (expanded when shouldn't be))

note: code , issue has not been tested on ios or uwp not have access these platforms test on.


Comments

Popular posts from this blog

Command prompt result in label. Python 2.7 -

javascript - How do I use URL parameters to change link href on page? -

amazon web services - AWS Route53 Trying To Get Site To Resolve To www -